日志函数 附 源码 详解

2025-11-13 08:05:26

1、日志函数的实现的完整的代码:

void fkTrace(int nLevel, const char* pcFormat, ...)

{

static char pcFile[256];

/// 获取当前时间

time_t rawTime = { 0 };

time(&rawTime);

struct  tm* t = localtime(&rawTime);

if (0 == *pcFile)

{

/// 创建日志目录

char pcFolder[256] = { 0 };

GetCurrentDirectoryA(sizeof(pcFolder), pcFolder);

strcat(pcFolder, "\\log");

CreateDirectoryA(pcFolder, NULL);

/// 获取log日志文件名称

sprintf(pcFile, "%s\\%04d-%02d-%02d %02d-%02d-%02d.log", pcFolder, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

AllocConsole();

freopen("CONOUT$", "w", stdout);

}

/// 解析字符串

char pcTrace[4096] = { 0 };

sprintf(pcTrace, "%04d-%02d-%02d %02d:%02d:%02d | ", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

va_list arglist;

va_start(arglist, pcFormat);

vsprintf(strrchr(pcTrace, '\0'), pcFormat, arglist);

va_end(arglist);

/// 打印到控制台

fputs(pcTrace, stdout);

/// 打印到文件

FILE* fp = fopen(pcFile, "a+");

if (NULL != fp)

{

fputs(pcTrace, fp);

fclose(fp);

}

/// 将警告和错误消息用 messagebox 提示

if (nLevel <= 1)

{

MessageBoxA(NULL, pcTrace, "errinfo", MB_OK);

}

}

2、日志函数的宏控制代码:

调试时的代码:

#define LOG_ERROR(...) fkTrace(0, __VA_ARGS__)

#define LOG_WARN(...) fkTrace(1, __VA_ARGS__)

#define LOG_DEBUG(...) fkTrace(2, __VA_ARGS__)

#define LOG_INFO(...) fkTrace(3, __VA_ARGS__)

发布时的代码:

#define LOG_ERROR(...) fkTrace(0, __VA_ARGS__)

#define LOG_WARN(...) /// fkTrace(1, __VA_ARGS__)

#define LOG_DEBUG(...) /// fkTrace(2, __VA_ARGS__)

#define LOG_INFO(...) /// fkTrace(3, __VA_ARGS__)

3、根据错误ID返回对应的错误信息:

char* fkGetErrorInfo(int nErrno)

{

static char szErr[4000] = { 0 };

memset(szErr, 0, sizeof(szErr));

DWORD dwLanguageId = MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED); 

/// MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); /// 美国英语 (US)

/// MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK); /// 英国英语 (GB)

/// MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED); /// 简体中文 (zh)

/// MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL); /// 繁体中文 (zh)

/// LANG_USER_DEFAULT 用户默认

/// LANG_SYSTEM_DEFAULT 系统默认

FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nErrno, dwLanguageId, (LPSTR)&szErr, sizeof(szErr), NULL);

int nLen = strlen(szErr);

/// 去掉最后的换行符 "/r/n"

if (nLen > 2)

{

if (0 == memcmp(szErr + nLen - 2, "\r\n", 2))

{

szErr[nLen - 2] = 0;

}

}

return szErr;

}

效果如下:

日志函数 附 源码 详解

4、返回最后一个错误信息对应的字符串:

#define ERRINFO fkGetErrorInfo(GetLastError())

5、最后的效果图如下:

日志函数 附 源码 详解

日志函数 附 源码 详解

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢