日志函数 附 源码 详解
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、最后的效果图如下:

