C++实现日志功能:简单实现及第三方库汇总
C++实现日志功能:log4c(Win10+VS2017)
C++实现日志功能:log4cplus(Win10+VS2017)
这里废话不多说,直接上代码。
/*
* This source file is part of 爱看书的小沐
* @author: tomcat
* @date: 2022-01-20
*/
#pragma once
enum LOG_FLAGS {
LOG_INFO = 1 << 0,
LOG_WARN = 1 << 1,
LOG_ERROR = 1 << 2,
LOG_DATE = 1 << 3,
LOG_PRINTF = 1 << 4,
LOG_MESSAGEBOX = 1 << 5,
LOG_OUTPUTDEBUG = 1 << 6,
LOG_FILE = 1 << 7,
LOG_SENDMESSAGE = 1 << 8,
LOG_PIPE = 1 << 9,
LOG_EDIT = 1 << 10,
LOG_NOLF = 1 << 11,
LOG_DATE2 = 1 << 12,
};
/*------------------------------------------------------*/
namespace FxLib { namespace Debug {
void LogShort(const TCHAR* logFileName, const TCHAR* log2write, bool bWrap = true);
void LogLong(unsigned nFlags, void* pData, const char* fmt, ...);
void ConsoleStart();
void ConsoleEnd();
void OutputDebugStringF(const _TCHAR *szFmt, ...);
void MessageBoxF(const _TCHAR *szFmt, const _TCHAR *szCaption, unsigned int uType, ...);
}} // namespace FxLib::Debug
/*------------------------------------------------------*/
#define FXLOG_FILE(file, _format, ...) FxLib::Debug::LogLong(LOG_FILE, (void*)file, _format, ##__VA_ARGS__)
#define FXLOG_FILEDATE(file, _format, ...) FxLib::Debug::LogLong(LOG_FILE|LOG_DATE, (void*)file, _format, ##__VA_ARGS__)
#define FXLOG_OUTPUT(_format, ...) FxLib::Debug::LogLong(LOG_OUTPUTDEBUG, NULL, _format, ##__VA_ARGS__)
#define FXLOG_EDIT(hWndEdit, _format, ...) FxLib::Debug::LogLong(LOG_EDIT, (void*)hWndEdit, _format, ##__VA_ARGS__)
#define FXLOG_EDITDATE(hWndEdit, _format, ...) FxLib::Debug::LogLong(LOG_EDIT|LOG_DATE, (void*)hWndEdit, _format, ##__VA_ARGS__)
#define FXLOG_EDITDATE2(hWndEdit, _format, ...) FxLib::Debug::LogLong(LOG_EDIT|LOG_DATE2, (void*)hWndEdit, _format, ##__VA_ARGS__)
/*
* This source file is part of 爱看书的小沐
* @author: tomcat
* @date: 2022-01-20
*/
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include "FxDebugLog.h"
namespace FxLib { namespace Debug {
void LogShort(const TCHAR* logFileName, const TCHAR* log2write, bool bWrap)
{
#ifdef _UNICODE
FILE *fp = _tfopen(logFileName, _T("a+,ccs=UTF-8"));
#else
FILE *fp = _tfopen(logFileName, _T("a+"));
#endif
if(fp == NULL) return;
fwrite(log2write, sizeof(log2write[0]), _tcslen(log2write), fp);
if(bWrap) _fputtc('\n', fp);
fflush(fp);
fclose(fp);
}
void LogLong(unsigned nFlags, void* pData, const char* fmt, ...)
{
//get time string
char szTime[64];
memset(szTime, 0, sizeof(szTime));
if(nFlags & LOG_DATE) {
SYSTEMTIME systime;
::GetLocalTime(&systime);
sprintf_s(szTime, 64, "[%04d-%02d-%02d %02d:%02d:%02d]",
systime.wYear, systime.wMonth, systime.wDay,
systime.wHour, systime.wMinute, systime.wSecond);
}
else if(nFlags & LOG_DATE2) {
SYSTEMTIME systime;
::GetLocalTime(&systime);
sprintf_s(szTime, 64, "[%02d:%02d:%02d]",
systime.wHour, systime.wMinute, systime.wSecond);
}
//create input string
const int buffer_size = 4096;
va_list args;
static char buffer[ buffer_size ];
memset(buffer, 0, sizeof(buffer));
va_start( args, fmt );
int len = vsprintf_s( buffer, buffer_size - 2, fmt, args );
va_end( args );
if ( len < 0 || len > buffer_size - 2 ) {
len = buffer_size - 2;
}
if(nFlags & LOG_NOLF) {
buffer[len] = '\0';
}
else {
buffer[len] = '\n';
buffer[len+1] = '\0';
}
//print log
static char szEdit[1024*4];
memset(szEdit, 0, sizeof(szEdit));
if(nFlags & LOG_DATE || nFlags & LOG_DATE2) {
strcat_s(szEdit, szTime);
strcat_s(szEdit, ": ");
}
strcat_s(szEdit, buffer);
if (nFlags & LOG_FILE) {
LPCSTR logFileName = (LPCSTR)pData;
LogShort(logFileName, szEdit, false);
}
else if (nFlags & LOG_EDIT) {
HWND hWndEdit = (HWND)pData;
int nLines = (int)::SendMessage(hWndEdit, EM_GETLINECOUNT, 0, 0);
#define BUFFER_SIZE 1024*1024*4
static char buffer[BUFFER_SIZE] = "\0";
int bufLen = ::GetWindowText(hWndEdit, buffer, BUFFER_SIZE);
if(bufLen < BUFFER_SIZE && bufLen >= 2 && !(buffer[bufLen - 1] == '\n' && buffer[bufLen - 2] == '\r'))
strcat_s(buffer, "\r\n");
strcat_s(buffer, szEdit);
::SendMessage(hWndEdit, EM_SETSEL, bufLen, bufLen);
::SendMessage(hWndEdit, EM_SCROLLCARET, 0, 0L);
::SetFocus(hWndEdit);
::SendMessage(hWndEdit, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)buffer);
::SendMessage(hWndEdit, EM_LINESCROLL, 0, nLines);
if(nLines > 1000) {
::SetWindowTextA(hWndEdit, "");
::SendMessage(hWndEdit, EM_LINESCROLL, 0, 0);
}
}
else if (nFlags & LOG_PRINTF) {
printf(szEdit);
}
else if (nFlags & LOG_MESSAGEBOX) {
::MessageBoxA(NULL, szEdit, "Log", MB_OK);
}
else if (nFlags & LOG_OUTPUTDEBUG) {
::OutputDebugStringA(szEdit);
}
}
void ConsoleStart()
{
AllocConsole();
freopen("conin$", "r", stdin);
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);
}
void ConsoleEnd()
{
fclose(stdin);
fclose(stdout);
fclose(stderr);
FreeConsole();
}
void OutputDebugStringF(const _TCHAR *szFmt, ...)
{
va_list vaArgs;
va_start(vaArgs, szFmt);
// wvsprintf guarantees not to write more than 1024 chars
static _TCHAR szBuf[1024];
wvsprintf(szBuf, szFmt, vaArgs);
va_end(vaArgs);
OutputDebugString(szBuf);
}
void MessageBoxF(const _TCHAR *szFmt, const _TCHAR *szCaption, unsigned int uType, ...)
{
va_list vaArgs;
va_start(vaArgs, uType);
// wvsprintf guarantees not to write more than 1024 chars
static _TCHAR szBuf[1024];
wvsprintf(szBuf, szFmt, vaArgs);
va_end(vaArgs);
MessageBox(NULL, szBuf, szCaption, uType);
}
}} // namespace FxLib::Debug
https://sourceforge.net/projects/log4cplus/
https://github.com/log4cplus/log4cplus
https://logging.apache.org/log4j/2.x/index.html
https://logging.apache.org/log4j/2.x/download.html
https://logging.apache.org/log4cxx/latest_stable/
https://github.com/apache/logging-log4cxx
http://log4cpp.sourceforge.net/
http://log4c.sourceforge.net/
http://log4qt.sourceforge.net/
https://www.boost.org/
https://www.boost.org/users/download/
https://boostorg.jfrog.io/artifactory/main/release/
https://sourceforge.net/projects/boost/files/boost/
https://github.com/boostorg/boost
https://github.com/google/glog
如果你觉得这些文字有一点点用处,可以给作者点个赞;╮( ̄▽ ̄)╭
如果你感觉作者写的不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进。o_O???
谢谢各位小伙伴们啦( ´ ▽ ‘)ノ ( ´ ▽ ` )っ!!!