Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
jlib
Commits
3363aa77
Commit
3363aa77
authored
May 13, 2016
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactored log
parent
d765bdaa
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
304 additions
and
527 deletions
+304
-527
Log.h
Log.h
+262
-489
chrono_wrapper.h
chrono_wrapper.h
+41
-0
global.h
global.h
+1
-38
No files found.
Log.h
View file @
3363aa77
// Log.h: interface for the CLog class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#endif
/*
日志类CLog
简述:单例的日志输出类,使用时会自动构造,但因为要保证日志类最后一个析构,需要手动释放
功能:写日志,输出TRACE内容到dbgview,console。
使用:
使用函数
static void SetOutputLogFileName(LPCTSTR szFileName);
static void SetOutputConsole(BOOL bFlag);
static void SetOutputDbgView(BOOL bFlag);
static void SetOutputLogFile(BOOL bFlag);
来设置输出日志的方式
使用TRACE或使用函数static void WriteLog(const char* format, ...);写日志,可接受可变参数
释放:在程序退出时(ExitInstance()函数的最后)调用CLog::Release()释放引用计数
Warnning:
The singleton pattern that log implemented is not thread-safe,
you should call log::get_instance() once in your main thread,
or else it might cause multiple constructions.
*/
#if !defined(AFX_ERRORLOG_H__46D664F1_E737_46B7_9813_2EF1415FF884__INCLUDED_)
#define AFX_ERRORLOG_H__46D664F1_E737_46B7_9813_2EF1415FF884__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <assert.h>
#include <mutex>
#include <fstream>
#include <string>
#include <memory>
#include <cstring>
#include <stdint.h>
#include <stdarg.h>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include "utf8.h"
#include "chrono_wrapper.h"
//#include "dbghlpapi.h"
namespace
jlib
{
//#ifdef TRACE
//#undef TRACE
//#define TRACE CLog::WriteLog
//#endif
#define JLOG jlib::log::log_utf16
#define JLOGA jlib::log::log_utf8
#define JLOGW jlib::log::log_utf16
#define JLOGB(b, l) jlib::log::dump_hex(b, l)
#define JLOGASC(b, l) jlib::log::dump_ascii(b, l)
namespace
jlib
#define IMPLEMENT_CLASS_LOG_STATIC_MAMBER jlib::log* jlib::log::instance_ = nullptr;
class
log
:
private
boost
::
noncopyable
{
enum
{
max_output_size
=
1024
*
64
,
max_single_log_file_size
=
1024
*
1024
*
10
};
#define IMPLEMENT_CLASS_LOG_STATIC_MEMBER \
std
::
mutex
CLog
::
m_cs
;
\
std
::
mutex
CLog
::
m_lockForSingleton
;
\
char
CLog
::
m_ansiBuf
[
MAX_OUTPUT_LEN
];
\
wchar_t
CLog
::
m_utf16Buf
[
MAX_OUTPUT_LEN
];
\
CLog
*
CLog
::
m_pInstance
=
NULL
;
\
TCHAR
CLog
::
g_szFileName
[
1024
]
=
{
0
};
/*
#define TRACEFUNCNAME \
CString str = _T("");\
INIT_SYM(TRUE);\
str.Format("File %s, line %d, funcname %s\n", __FILE__, __LINE__, __FUNCNAME__);\
OutputDebugString(str);\
UNINIT_SYM();\
*/
#define MAX_OUTPUT_LEN (1024 * 64)
#define MAX_FILE_LEN (1024 * 1024 * 10)
//static TCHAR g_szFileName[1024] = {0};
class
CLog
private
:
bool
log_to_file_
=
false
;
bool
log_to_dbg_view_
=
true
;
bool
running_
=
false
;
std
::
ofstream
log_file_
;
std
::
string
log_file_foler_
=
""
;
std
::
string
log_file_path_
=
""
;
std
::
string
line_prefix_
=
""
;
std
::
mutex
lock_
;
static
log
*
instance_
;
public
:
// initializers, they should be called right after get_instance
void
set_line_prifix
(
const
std
::
string
&
prefix
)
{
line_prefix_
=
prefix
;
}
void
set_output_to_dbg_view
(
bool
b
=
true
)
{
log_to_dbg_view_
=
b
;
}
void
set_log_file_foler
(
const
std
::
string
&
folder_path
)
{
log_file_foler_
=
folder_path
.
empty
()
?
""
:
folder_path
+
"
\\
"
;
}
void
set_output_to_file
(
bool
b
=
true
)
{
log_to_file_
=
b
;
if
(
b
)
create_file_name
();
}
auto
get_log_file_path
()
const
{
return
log_file_path_
;
}
public
:
static
log
*
get_instance
()
{
private
:
#pragma region private members
double
exe_time
;
LARGE_INTEGER
freq
;
LARGE_INTEGER
start_t
,
stop_t
;
BOOL
m_bOutputLogFile
;
BOOL
m_bOutputDbgView
;
BOOL
m_bOutputConsole
;
BOOL
m_bConsoleOpened
;
BOOL
m_bDbgviewOpened
;
BOOL
m_bLogFileOpened
;
BOOL
m_bRunning
;
FILE
*
m_pLogFile
;
PROCESS_INFORMATION
pi
;
static
TCHAR
g_szFileName
[
1024
];
static
std
::
mutex
m_cs
;
static
std
::
mutex
m_lockForSingleton
;
static
char
m_ansiBuf
[
MAX_OUTPUT_LEN
];
static
wchar_t
m_utf16Buf
[
MAX_OUTPUT_LEN
];
static
CLog
*
m_pInstance
;
#pragma endregion
public
:
#pragma region public functions
static
const
wchar_t
*
GetLogFilePath
()
{
return
g_szFileName
;
}
static
CLog
*
GetInstance
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
m_lockForSingleton
);
if
(
CLog
::
m_pInstance
==
NULL
)
{
static
CLog
log
;
CLog
::
m_pInstance
=
&
log
;
}
return
CLog
::
m_pInstance
;
/*
Warnning:
The singleton pattern that log implemented is not thread-safe,
you should call log::get_instance() once in your main thread,
or else it might cause multiple constructions.
*/
if
(
log
::
instance_
==
nullptr
)
{
static
log
log_
;
log
::
instance_
=
&
log_
;
}
return
log
::
instance_
;
}
~
CLog
()
{
m_bRunning
=
FALSE
;
//WaitTillThreadExited(m_handle);
if
(
m_bConsoleOpened
)
OpenConsole
(
FALSE
);
if
(
m_bDbgviewOpened
)
OpenDbgview
(
FALSE
);
if
(
m_bLogFileOpened
)
CloseLogFile
();
//DeleteCriticalSection(&m_cs);
#ifdef _DEBUG
TCHAR
buf
[
1024
],
out
[
1024
];
wsprintf
(
buf
,
_T
(
"%s
\n
"
),
_T
(
"CLog::~CLog() destruction"
));
FormatBuf
(
buf
,
out
,
1024
);
OutputDebugString
(
out
);
#endif
}
~
log
()
{
running_
=
false
;
static
void
SetOutputLogFileName
(
LPCTSTR
szLastName
)
{
lstrcpy
(
g_szFileName
,
szLastName
);
if
(
log_file_
.
is_open
())
{
log_file_
.
close
();
}
static
void
SetOutputConsole
(
BOOL
bFlag
)
{
CLog
*
plog
=
CLog
::
GetInstance
();
plog
->
m_bOutputConsole
=
bFlag
;
plog
->
OpenConsole
(
bFlag
);
}
#ifdef _DEBUG
output_to_dbg_view
(
"log::~log
\n
"
);
#endif
}
static
void
SetOutputDbgView
(
BOOL
bFlag
)
{
CLog
*
plog
=
CLog
::
GetInstance
();
plog
->
m_bOutputDbgView
=
bFlag
;
//plog->OpenDbgview(bFlag);
}
public
:
static
void
SetOutputLogFile
(
BOOL
bFlag
)
{
CLog
*
plog
=
CLog
::
GetInstance
();
plog
->
m_bOutputLogFile
=
bFlag
;
if
(
plog
->
m_bOutputLogFile
&&
lstrlen
(
g_szFileName
)
==
0
)
plog
->
CreateFileName
();
}
// static operations
static
void
Dump
(
const
char
*
buff
,
size_t
buff_len
)
{
try
{
CLog
*
plog
=
CLog
::
GetInstance
();
if
(
plog
==
NULL
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
m_cs
);
if
(
plog
->
m_bOutputLogFile
||
plog
->
m_bOutputDbgView
||
plog
->
m_bOutputConsole
)
{
size_t
output_len
=
buff_len
*
6
+
64
;
wchar_t
*
output
=
new
wchar_t
[
output_len
];
output
[
0
]
=
0
;
wchar_t
c
[
64
]
=
{
0
};
swprintf_s
(
c
,
L"len %d
\n
"
,
buff_len
);
wcscat_s
(
output
,
output_len
,
c
);
for
(
size_t
i
=
0
;
i
<
buff_len
;
i
++
)
{
swprintf_s
(
c
,
L"%02X "
,
static_cast
<
unsigned
char
>
(
buff
[
i
]));
wcscat_s
(
output
,
output_len
,
c
);
if
(
i
>
0
&&
(
i
+
1
)
%
16
==
0
)
{
wcscat_s
(
output
,
output_len
,
L"
\n
"
);
}
static
void
dump_hex
(
const
char
*
buff
,
size_t
buff_len
)
{
try
{
log
*
instance
=
log
::
get_instance
();
if
(
instance
->
log_to_file_
||
instance
->
log_to_dbg_view_
)
{
size_t
output_len
=
buff_len
*
6
+
64
;
std
::
unique_ptr
<
char
[]
>
output
=
std
::
unique_ptr
<
char
[]
>
(
new
char
[
output_len
]);
output
[
0
]
=
0
;
char
c
[
64
]
=
{
0
};
std
::
sprintf
(
c
,
"len %d
\n
"
,
buff_len
);
std
::
strcat
(
output
.
get
(),
c
);
for
(
size_t
i
=
0
;
i
<
buff_len
;
i
++
)
{
std
::
sprintf
(
c
,
"%02X "
,
static_cast
<
unsigned
char
>
(
buff
[
i
]));
std
::
strcat
(
output
.
get
(),
c
);
if
(
i
>
0
&&
(
i
+
1
)
%
16
==
0
)
{
std
::
strcat
(
output
.
get
(),
"
\n
"
);
}
wcscat_s
(
output
,
output_len
,
L"
\n
"
);
plog
->
Output
(
output
);
delete
[]
output
;
}
}
catch
(...)
{
assert
(
0
);
std
::
strcat
(
output
.
get
(),
"
\n
"
);
instance
->
output
(
output
.
get
()
);
}
}
catch
(...)
{
assert
(
0
);
}
}
static
void
DumpAsc
(
const
char
*
buff
,
size_t
buff_len
)
{
try
{
CLog
*
plog
=
CLog
::
GetInstance
();
if
(
plog
==
NULL
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
m_cs
);
if
(
plog
->
m_bOutputLogFile
||
plog
->
m_bOutputDbgView
||
plog
->
m_bOutputConsole
)
{
size_t
output_len
=
buff_len
*
6
+
64
;
wchar_t
*
output
=
new
wchar_t
[
output_len
];
output
[
0
]
=
0
;
wchar_t
c
[
64
]
=
{
0
};
swprintf_s
(
c
,
L"len %d
\n
"
,
buff_len
);
wcscat_s
(
output
,
output_len
,
c
);
for
(
size_t
i
=
0
;
i
<
buff_len
;
i
++
)
{
swprintf_s
(
c
,
L"%C "
,
static_cast
<
unsigned
char
>
(
buff
[
i
]));
wcscat_s
(
output
,
output_len
,
c
);
if
(
i
>
0
&&
(
i
+
1
)
%
16
==
0
)
{
wcscat_s
(
output
,
output_len
,
L"
\n
"
);
}
static
void
dump_ascii
(
const
char
*
buff
,
size_t
buff_len
)
{
try
{
log
*
instance
=
log
::
get_instance
();
if
(
instance
->
log_to_file_
||
instance
->
log_to_dbg_view_
)
{
size_t
output_len
=
buff_len
*
6
+
64
;
std
::
unique_ptr
<
char
[]
>
output
=
std
::
unique_ptr
<
char
[]
>
(
new
char
[
output_len
]);
output
[
0
]
=
0
;
char
c
[
64
]
=
{
0
};
std
::
sprintf
(
c
,
"len %d
\n
"
,
buff_len
);
std
::
strcat
(
output
.
get
(),
c
);
for
(
size_t
i
=
0
;
i
<
buff_len
;
i
++
)
{
std
::
sprintf
(
c
,
"%C "
,
static_cast
<
unsigned
char
>
(
buff
[
i
]));
std
::
strcat
(
output
.
get
(),
c
);
if
(
i
>
0
&&
(
i
+
1
)
%
16
==
0
)
{
std
::
strcat
(
output
.
get
(),
"
\n
"
);
}
wcscat_s
(
output
,
output_len
,
L"
\n
"
);
plog
->
Output
(
output
);
delete
[]
output
;
}
}
catch
(...)
{
assert
(
0
);
std
::
strcat
(
output
.
get
(),
"
\n
"
);
instance
->
output
(
output
.
get
()
);
}
}
catch
(...)
{
assert
(
0
);
}
}
/*static void WriteLog(const TCHAR* format, ...)
{
try {
CLog* plog = CLog::GetInstance();
if (plog == NULL)
return;
std::lock_guard<std::mutex> lock(m_cs);
if (plog->m_bOutputLogFile || plog->m_bOutputDbgView || plog->m_bOutputConsole) {
static TCHAR buf[MAX_OUTPUT_LEN], output[MAX_OUTPUT_LEN], *p;
p = buf;
va_list args;
va_start(args, format);
p += _vsntprintf_s(p, MAX_OUTPUT_LEN - 1, MAX_OUTPUT_LEN - 1, format, args);
va_end(args);
while ((p > buf) && _istspace(*(p - 1)))
*--p = _T('\0');
*p++ = _T('\r');
*p++ = _T('\n');
*p = _T('\0');
plog->FormatBuf(buf, output);
plog->Output(output);
}
} catch (...) {
assert(0);
}
}*/
static
void
WriteLogW
(
const
wchar_t
*
format
,
...)
{
try
{
CLog
*
plog
=
CLog
::
GetInstance
();
if
(
plog
==
NULL
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
m_cs
);
if
(
plog
->
m_bOutputLogFile
||
plog
->
m_bOutputDbgView
||
plog
->
m_bOutputConsole
)
{
static
wchar_t
buf
[
MAX_OUTPUT_LEN
],
*
p
;
p
=
buf
;
va_list
args
;
va_start
(
args
,
format
);
p
+=
_vsnwprintf_s
(
p
,
MAX_OUTPUT_LEN
-
1
,
MAX_OUTPUT_LEN
-
1
,
format
,
args
);
va_end
(
args
);
while
((
p
>
buf
)
&&
iswspace
(
*
(
p
-
1
)))
*--
p
=
'\0'
;
*
p
++
=
'\r'
;
*
p
++
=
'\n'
;
*
p
=
'\0'
;
#if defined(_UNICODE) || defined(UNICODE)
wchar_t
output
[
MAX_OUTPUT_LEN
];
plog
->
FormatBuf
(
buf
,
output
);
plog
->
Output
(
output
);
#else
char
output
[
MAX_OUTPUT_LEN
];
if
(
Utf16ToAnsiUseCharArray
(
buf
,
m_ansiBuf
,
MAX_OUTPUT_LEN
)){
plog
->
FormatBuf
(
m_ansiBuf
,
output
);
plog
->
Output
(
output
);
}
else
{
char
*
ansiOut
=
Utf16ToAnsi
(
buf
);
plog
->
FormatBuf
(
ansiOut
,
output
);
plog
->
Output
(
output
);
SAFEDELETEARR
(
ansiOut
);
}
#endif
}
}
catch
(...)
{
assert
(
0
);
static
void
log_utf16
(
const
wchar_t
*
format
,
...)
{
try
{
log
*
instance
=
log
::
get_instance
();
if
(
instance
->
log_to_file_
||
instance
->
log_to_dbg_view_
)
{
static
wchar_t
buf
[
max_output_size
],
*
p
;
p
=
buf
;
va_list
args
;
va_start
(
args
,
format
);
p
+=
_vsnwprintf_s
(
p
,
max_output_size
-
1
,
max_output_size
-
1
,
format
,
args
);
va_end
(
args
);
while
((
p
>
buf
)
&&
iswspace
(
*
(
p
-
1
)))
*--
p
=
'\0'
;
*
p
++
=
'\r'
;
*
p
++
=
'\n'
;
*
p
=
'\0'
;
instance
->
output
(
instance
->
format_msg
(
utf8
::
w2a
(
buf
)));
}
}
catch
(...)
{
assert
(
0
);
}
}
static
void
WriteLogA
(
const
char
*
format
,
...)
{
try
{
CLog
*
plog
=
CLog
::
GetInstance
();
if
(
plog
==
NULL
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
m_cs
);
if
(
plog
->
m_bOutputLogFile
||
plog
->
m_bOutputDbgView
||
plog
->
m_bOutputConsole
)
{
static
char
buf
[
MAX_OUTPUT_LEN
],
*
p
;
p
=
buf
;
va_list
args
;
va_start
(
args
,
format
);
p
+=
_vsnprintf_s
(
p
,
MAX_OUTPUT_LEN
-
1
,
MAX_OUTPUT_LEN
-
1
,
format
,
args
);
va_end
(
args
);
while
((
p
>
buf
)
&&
_istspace
(
*
(
p
-
1
)))
*--
p
=
'\0'
;
*
p
++
=
'\r'
;
*
p
++
=
'\n'
;
*
p
=
'\0'
;
#if defined(_UNICODE) || defined(UNICODE)
wchar_t
output
[
MAX_OUTPUT_LEN
];
if
(
AnsiToUtf16Array
(
buf
,
m_utf16Buf
,
MAX_OUTPUT_LEN
))
{
plog
->
FormatBuf
(
m_utf16Buf
,
output
);
plog
->
Output
(
output
);
}
else
{
wchar_t
*
wBuf
=
AnsiToUtf16
(
buf
);
plog
->
FormatBuf
(
wBuf
,
output
);
plog
->
Output
(
output
);
SAFEDELETEARR
(
wBuf
);
}
#else
char
output
[
MAX_OUTPUT_LEN
];
plog
->
FormatBuf
(
buf
,
output
);
plog
->
Output
(
output
);
#endif
}
}
catch
(...)
{
assert
(
0
);
static
void
log_utf8
(
const
char
*
format
,
...)
{
try
{
log
*
instance
=
log
::
get_instance
();
if
(
instance
->
log_to_file_
||
instance
->
log_to_dbg_view_
)
{
static
char
buf
[
max_output_size
],
*
p
;
p
=
buf
;
va_list
args
;
va_start
(
args
,
format
);
p
+=
_vsnprintf_s
(
p
,
max_output_size
-
1
,
max_output_size
-
1
,
format
,
args
);
va_end
(
args
);
while
((
p
>
buf
)
&&
isspace
(
*
(
p
-
1
)))
*--
p
=
'\0'
;
*
p
++
=
'\r'
;
*
p
++
=
'\n'
;
*
p
=
'\0'
;
instance_
->
output
(
instance
->
format_msg
(
buf
));
}
}
catch
(...)
{
assert
(
0
);
}
}
#pragma endregion
protected
:
#pragma region protected functions
CLog
()
:
m_pLogFile
(
NULL
),
m_bOutputLogFile
(
FALSE
),
m_bOutputDbgView
(
FALSE
),
m_bOutputConsole
(
FALSE
),
m_bConsoleOpened
(
FALSE
),
m_bDbgviewOpened
(
FALSE
),
m_bLogFileOpened
(
FALSE
),
m_bRunning
(
TRUE
)
{
QueryPerformanceFrequency
(
&
freq
);
//OutputDebugString(_T("The frequency of your pc is 0x%X.\n"), freq.QuadPart);
QueryPerformanceCounter
(
&
start_t
);
memset
(
g_szFileName
,
0
,
sizeof
(
g_szFileName
));
TCHAR
out
[
128
]
=
{
0
};
wsprintf
(
out
,
_T
(
"CLog construction addr: %p
\n
"
),
this
);
OutputDebugString
(
out
);
memset
(
&
pi
,
0
,
sizeof
(
pi
));
//InitializeCriticalSection(&m_cs);
}
LPCTSTR
GetAppRunTime
()
{
static
TCHAR
szTime
[
128
];
memset
(
szTime
,
0
,
sizeof
szTime
);
QueryPerformanceCounter
(
&
stop_t
);
exe_time
=
1e3
*
(
stop_t
.
QuadPart
-
start_t
.
QuadPart
)
/
freq
.
QuadPart
;
WORD
day
,
hour
,
min
,
sec
;
protected
:
sec
=
static_cast
<
unsigned
short
>
(
static_cast
<
unsigned
long
>
(
exe_time
/
1000
)
%
60
);
min
=
static_cast
<
unsigned
short
>
(
static_cast
<
unsigned
long
>
(
exe_time
/
1000
/
60
)
%
60
);
hour
=
static_cast
<
unsigned
short
>
((
exe_time
/
1000
/
60
)
/
60
);
day
=
static_cast
<
unsigned
short
>
(
exe_time
/
1000
.
0
/
60
.
0
/
60
.
0
/
24
);
log
()
{
running_
=
true
;
char
out
[
128
]
=
{
0
};
sprintf
(
out
,
"log construction addr: %p
\n
"
,
this
);
output_to_dbg_view
(
out
);
}
double
ms
=
exe_time
-
(
int
)(
exe_time
)
+
((
int
)(
exe_time
)
%
1000
);
wsprintf
(
szTime
,
_T
(
"%dday%02d:%02d:%02ds.%3.6fms"
),
day
,
hour
,
min
,
sec
,
ms
);
return
szTime
;
bool
open_log_file
()
{
if
(
!
log_file_
.
is_open
())
{
log_file_
.
open
(
log_file_path_
);
}
return
log_file_
.
is_open
();
}
void
create_file_name
()
{
auto
s
=
now_to_string
();
std
::
replace
(
s
.
begin
(),
s
.
end
(),
' '
,
'_'
);
std
::
replace
(
s
.
begin
(),
s
.
end
(),
':'
,
'-'
);
log_file_path_
=
log_file_foler_
+
s
+
".log"
;
}
std
::
string
format_msg
(
const
std
::
string
&
msg
)
{
return
line_prefix_
+
" "
+
now_to_string
(
true
)
+
" ---- "
+
msg
;
}
void
output
(
const
std
::
string
&
msg
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
lock_
);
if
(
log_to_file_
)
{
output_to_log_file
(
msg
);
}
static
const
wchar_t
*
GetPrivateLogPath
()
{
static
wchar_t
strPrivateMapFolder
[
1024
]
=
{
0
};
static
BOOL
b
=
TRUE
;
if
(
b
)
{
wsprintf
(
strPrivateMapFolder
,
_T
(
"%s
\\
Log"
),
GetModuleFilePath
());
b
=
FALSE
;
if
(
log_to_dbg_view_
)
{
output_to_dbg_view
(
msg
);
}
}
void
output_to_log_file
(
const
std
::
string
&
msg
)
{
if
(
log_file_
.
is_open
())
{
auto
size
=
log_file_
.
tellp
();
if
(
size
>
max_single_log_file_size
)
{
log_file_
.
close
();
create_file_name
();
open_log_file
();
}
return
strPrivateMapFolder
;
}
void
Output
(
const
TCHAR
*
out
)
{
if
(
m_bOutputLogFile
)
{
OutputFile
(
out
);
}
#ifdef _DEBUG
OutputDebugString
(
out
);
#else
if
(
m_bOutputDbgView
){
OutputDebugString
(
out
);
}
#endif
if
(
m_bOutputConsole
)
{
_tprintf
(
out
);
}
if
(
!
log_file_
.
is_open
())
{
open_log_file
();
}
DWORD
FormatBuf
(
const
TCHAR
*
oldBuf
,
TCHAR
*
newBuf
,
DWORD
max_new_buff_len
=
MAX_OUTPUT_LEN
)
{
static
SYSTEMTIME
st
;
static
TCHAR
sztime
[
128
];
memset
(
sztime
,
0
,
sizeof
sztime
);
GetLocalTime
(
&
st
);
wsprintf
(
sztime
,
_T
(
"HB %04d-%02d-%02d-w%d %02d:%02d:%02d.%03d ---- "
),
st
.
wYear
,
st
.
wMonth
,
st
.
wDay
,
(
st
.
wDayOfWeek
!=
0
)
?
st
.
wDayOfWeek
:
7
,
st
.
wHour
,
st
.
wMinute
,
st
.
wSecond
,
st
.
wMilliseconds
);
lstrcpy
(
newBuf
,
sztime
);
if
(
static_cast
<
DWORD
>
(
lstrlen
(
sztime
)
+
lstrlen
(
oldBuf
))
<
max_new_buff_len
)
{
lstrcat
(
newBuf
,
oldBuf
);
}
return
static_cast
<
DWORD
>
(
lstrlen
(
newBuf
));
if
(
log_file_
.
is_open
())
{
log_file_
.
write
(
msg
.
c_str
(),
msg
.
size
());
}
}
void
OutputFile
(
const
TCHAR
*
buf
)
{
if
(
m_pLogFile
==
NULL
)
m_pLogFile
=
OpenLogFile
();
if
(
m_pLogFile
!=
NULL
)
{
fseek
(
m_pLogFile
,
0
,
SEEK_END
);
long
filelen
=
ftell
(
m_pLogFile
);
if
(
filelen
>=
MAX_FILE_LEN
)
{
fclose
(
m_pLogFile
);
CreateFileName
();
m_pLogFile
=
OpenLogFile
();
}
}
if
(
m_pLogFile
!=
NULL
)
{
fseek
(
m_pLogFile
,
0
,
SEEK_END
);
#if defined(_UNICODE) || defined(UNICODE)
if
(
Utf16ToAnsiUseCharArray
(
buf
,
m_ansiBuf
,
MAX_OUTPUT_LEN
))
{
fwrite
(
m_ansiBuf
,
1
,
strlen
(
m_ansiBuf
),
m_pLogFile
);
}
else
{
char
*
ansiOut
=
Utf16ToAnsi
(
buf
);
fwrite
(
ansiOut
,
1
,
strlen
(
ansiOut
),
m_pLogFile
);
SAFEDELETEARR
(
ansiOut
);
}
void
output_to_dbg_view
(
const
std
::
string
&
msg
)
{
#ifdef WIN32
OutputDebugStringA
(
msg
.
c_str
());
#else
fwrite
(
buf
,
1
,
strlen
(
buf
),
m_pLogFile
);
std
::
printf
(
msg
.
c_str
()
);
#endif
fflush
(
m_pLogFile
);
}
}
}
BOOL
OpenDbgview
(
BOOL
bOpen
)
{
static
STARTUPINFO
si
;
static
LPCTSTR
lpszAppName
=
_T
(
"dbgview.exe"
);
if
(
bOpen
)
{
if
(
!
m_bDbgviewOpened
)
{
memset
(
&
si
,
0
,
sizeof
(
STARTUPINFO
));
si
.
cb
=
sizeof
(
STARTUPINFO
);
si
.
dwFlags
=
STARTF_USESHOWWINDOW
;
si
.
wShowWindow
=
SW_SHOW
;
if
(
CreateProcess
(
lpszAppName
,
NULL
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
))
{
m_bDbgviewOpened
=
TRUE
;
}
}
}
else
if
(
m_bDbgviewOpened
)
{
CloseHandle
(
pi
.
hThread
);
CloseHandle
(
pi
.
hProcess
);
m_bDbgviewOpened
=
FALSE
;
}
return
bOpen
?
m_bDbgviewOpened
:
!
m_bDbgviewOpened
;
}
};
FILE
*
OpenLogFile
()
{
FILE
*
pfile
=
NULL
;
_tfopen_s
(
&
pfile
,
g_szFileName
,
_T
(
"r"
));
if
(
pfile
==
NULL
)
{
_tfopen_s
(
&
pfile
,
g_szFileName
,
_T
(
"wb"
));
if
(
pfile
==
NULL
)
{
MessageBox
(
NULL
,
_T
(
"Create log file failed."
),
NULL
,
0
);
ASSERT
(
0
);
return
NULL
;
}
}
else
{
fclose
(
pfile
);
_tfopen_s
(
&
pfile
,
g_szFileName
,
_T
(
"ab"
));
if
(
pfile
==
NULL
)
{
MessageBox
(
NULL
,
_T
(
"Open log file failed."
),
NULL
,
0
);
ASSERT
(
0
);
return
NULL
;
}
}
if
(
pfile
!=
NULL
)
m_bLogFileOpened
=
TRUE
;
return
pfile
;
}
void
CreateFileName
()
{
SYSTEMTIME
st
;
GetLocalTime
(
&
st
);
const
wchar_t
*
path
=
GetPrivateLogPath
();
CreateDirectory
(
path
,
NULL
);
wchar_t
exe
[
1024
]
=
{
0
};
GetModuleFileName
(
NULL
,
exe
,
1023
);
wsprintf
(
g_szFileName
,
_T
(
"%s
\\
%s-%04d-%02d-%02d-w%d-%02d-%02d-%02d"
),
path
,
CFileOper
::
GetFileNameFromPathName
(
exe
),
st
.
wYear
,
st
.
wMonth
,
st
.
wDay
,
(
st
.
wDayOfWeek
!=
0
)
?
st
.
wDayOfWeek
:
7
,
st
.
wHour
,
st
.
wMinute
,
st
.
wSecond
);
lstrcat
(
g_szFileName
,
_T
(
".log"
));
}
class
LogFunction
{
private
:
const
char
*
func_name_
;
std
::
chrono
::
steady_clock
::
time_point
begin_
;
public
:
LogFunction
(
const
char
*
func_name
)
:
func_name_
(
func_name
)
{
JLOGA
(
"%s in
\n
"
,
func_name_
);
begin_
=
std
::
chrono
::
steady_clock
::
now
();
}
~
LogFunction
()
{
auto
diff
=
std
::
chrono
::
steady_clock
::
now
()
-
begin_
;
auto
msec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
diff
);
JLOGA
(
"%s out, duration: %d(ms)
\n
"
,
func_name_
,
msec
.
count
());
}
};
void
CloseLogFile
()
{
if
(
m_pLogFile
!=
NULL
)
{
fflush
(
m_pLogFile
);
fclose
(
m_pLogFile
);
m_pLogFile
=
NULL
;
}
}
#define LOG_FUNCTION(func_name) jlib::LogFunction __log_function_object__(func_name);
#define AUTO_LOG_FUNCTION LOG_FUNCTION(__FUNCTION__);
BOOL
OpenConsole
(
BOOL
bOpen
)
{
static
FILE
*
pConsole
=
NULL
;
if
(
bOpen
)
{
if
(
!
m_bConsoleOpened
)
{
if
(
AllocConsole
())
{
SetConsoleTitle
(
_T
(
"output"
));
/*COORD coord;
coord.X = 120;
coord.Y = 60;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
FillConsoleOutputAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
120, coord, NULL);
SetConsoleScreenBufferSize(hStdOut, coord);
SMALL_RECT se;
se.Left = 0;
se.Top = 0;
se.Right = 100;
se.Bottom = 100;
SetConsoleWindowInfo(hStdOut, FALSE, &se);
*/
_tfreopen_s
(
&
pConsole
,
_T
(
"CONOUT$"
),
_T
(
"w"
),
stdout
);
m_bConsoleOpened
=
TRUE
;
}
}
return
m_bConsoleOpened
;
}
else
{
if
(
m_bConsoleOpened
)
{
fclose
(
pConsole
);
if
(
FreeConsole
())
{
m_bConsoleOpened
=
FALSE
;
}
}
return
!
m_bConsoleOpened
;
}
}
class
range_log
{
private
:
std
::
string
msg_
;
std
::
chrono
::
steady_clock
::
time_point
begin_
;
public
:
range_log
(
const
std
::
string
&
msg
)
:
msg_
(
msg
)
{
JLOGA
((
msg_
+
" in"
).
c_str
());
begin_
=
std
::
chrono
::
steady_clock
::
now
();
}
range_log
(
const
std
::
wstring
&
msg
)
:
msg_
()
{
msg_
=
utf8
::
w2a
(
msg
);
JLOGA
((
msg_
+
" in"
).
c_str
());
begin_
=
std
::
chrono
::
steady_clock
::
now
();
}
~
range_log
()
{
auto
diff
=
std
::
chrono
::
steady_clock
::
now
()
-
begin_
;
auto
msec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
diff
);
JLOGA
(
"%s out, duration: %d(ms)
\n
"
,
msg_
.
c_str
(),
msec
.
count
());
}
};
LPCTSTR
GetLastTimeLogFileName
()
{
return
g_szFileName
;
}
};
#pragma endregion
};
//CRITICAL_SECTION CLog::m_cs;
//int CLog::m_nRef = 0;
//char CLog::m_ansiBuf[MAX_OUTPUT_LEN] = {0};
//CLock CLog::m_lockForSingleton;
#endif // !defined(AFX_ERRORLOG_H__46D664F1_E737_46B7_9813_2EF1415FF884__INCLUDED_)
};
chrono_wrapper.h
0 → 100644
View file @
3363aa77
#
pragma
once
#include <chrono>
#include <string>
#include <ctime>
#include <sstream>
#include <iomanip>
namespace
jlib
{
std
::
string
time_point_to_string
(
const
std
::
chrono
::
system_clock
::
time_point
&
tp
,
bool
with_milliseconds
=
false
)
{
std
::
stringstream
ss
;
auto
t
=
std
::
chrono
::
system_clock
::
to_time_t
(
tp
);
std
::
tm
*
tm
=
std
::
localtime
(
&
t
);
ss
<<
std
::
put_time
(
tm
,
"%Y-%m-%d %H:%M:%S"
);
if
(
with_milliseconds
)
{
auto
ms
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
tp
.
time_since_epoch
());
auto
millis
=
ms
.
count
()
%
1000
;
ss
<<
'.'
<<
std
::
setw
(
3
)
<<
std
::
setfill
(
'0'
)
<<
millis
;
}
return
ss
.
str
();
}
std
::
chrono
::
system_clock
::
time_point
string_to_time_point
(
const
std
::
string
&
s
)
{
std
::
tm
tm
=
{
0
};
std
::
istringstream
ss
(
s
);
ss
>>
std
::
get_time
(
&
tm
,
"%Y-%m-%d %H:%M:%S"
);
return
std
::
chrono
::
system_clock
::
from_time_t
(
std
::
mktime
(
&
tm
));
}
std
::
string
now_to_string
(
bool
with_milliseconds
=
false
)
{
return
time_point_to_string
(
std
::
chrono
::
system_clock
::
now
(),
with_milliseconds
);
}
};
global.h
View file @
3363aa77
...
...
@@ -7,48 +7,11 @@
#include "utf8.h"
#include "mtverify.h"
#include "FileOper.h"
#include "
L
og.h"
#include "
l
og.h"
#include "MyWSAError.h"
#include "observer_macro.h"
namespace
jlib
{
#define JLOG CLog::WriteLogW
#define JLOGA CLog::WriteLogA
#define JLOGW CLog::WriteLogW
#define JLOGB(b, l) CLog::Dump(b, l)
#define JLOGASC(b, l) CLog::DumpAsc(b, l)
class
LogFunction
{
private
:
const
char
*
_func_name
;
std
::
chrono
::
steady_clock
::
time_point
_begin
;
public
:
LogFunction
(
const
char
*
func_name
)
:
_func_name
(
func_name
)
{
JLOGA
(
"%s in
\n
"
,
_func_name
);
_begin
=
std
::
chrono
::
steady_clock
::
now
();
}
~
LogFunction
()
{
auto
diff
=
std
::
chrono
::
steady_clock
::
now
()
-
_begin
;
auto
msec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
diff
);
JLOGA
(
"%s out, duration: %d(ms)
\n
"
,
_func_name
,
msec
.
count
());
}
};
#define LOG_FUNCTION(func_name) LogFunction _log_function_object(func_name);
#define AUTO_LOG_FUNCTION LOG_FUNCTION(__FUNCTION__)
class
range_log
{
private
:
std
::
wstring
_msg
;
std
::
chrono
::
steady_clock
::
time_point
_begin
;
public
:
range_log
(
const
std
::
wstring
&
msg
)
:
_msg
(
msg
)
{
JLOG
((
_msg
+
L" in"
).
c_str
());
_begin
=
std
::
chrono
::
steady_clock
::
now
();
}
~
range_log
()
{
auto
diff
=
std
::
chrono
::
steady_clock
::
now
()
-
_begin
;
auto
msec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
diff
);
JLOG
(
L"%s out, duration: %d(ms)
\n
"
,
_msg
.
c_str
(),
msec
.
count
());
}
};
#define NAMESPACE_END };
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment