C/C++格式化日志库实现代码
时间:2021-08-23 09:25:25|栏目:C代码|点击: 次
头文件如下:
/*****************************************************/ /* 跨平台日志函数,Linux下与windows下亲测有效 */ /*****************************************************/ #ifndef _LOG_FORMAT_H_ #define _LOG_FORMAT_H_ // 日志等级 enum LogLevel { _LOG_TRACE, _LOG_INFO, _LOG_WARN, _LOG_ERROR, _LOG_FATAL }; void LogFormat(const char *pszFileName, const int nLine, LogLevel Level, const char *Format, ...); /******************************************************/ /* 日志函数调用方法 _LOG(_LOG_FATAL, "%s", "sss"); */ /******************************************************/ #ifndef _LOG #define _LOG(Level, Format, ...) LogFormat(__FILE__, __LINE__, Level, Format, ##__VA_ARGS__) #endif #endif // _LOG_FORMAT_H_
源文件如下:
#include <string> #include <stdio.h> #include <stdarg.h> #include <stdint.h> #if defined __GNUC__ || defined LINUX #include <sys/time.h> #define MY_VA_LIST _G_va_list #else #include <windows.h> #define MY_VA_LIST va_list #endif #include "LogFormat.h" /* *最终生成的日志字符串最大长度,要特别注意 *超过此长度程序会崩溃,用户可以自定义长度 */ #define LOG_MAX 1024 /* *时间长度,不需要修改 */ #define FORMAT_TIME_SIZE 24 /* *日志等级字符串,与头文件中定义的枚举必须一致 */ static std::string g_LogLevel[] = { "TRACE","INFO","WARN","ERROR","FATAL" }; /* *内存申请函数,用户可以自定义 */ static char *NewBuf(const uint32_t unBufSize) { return new char[unBufSize]; } /* *内存释放函数,必须与NewBuf对应 */ static void DeleteBuf(char ** pszBuf) { if (NULL != *pszBuf) { delete[] *pszBuf; *pszBuf = NULL; } *pszBuf = NULL; } /* *获取当前时间字符串函数 *2018-08-08 08:08:08.888 */ static char* GetTime() { char *pszFormatTime = NewBuf(FORMAT_TIME_SIZE); #if defined __GNUC__ || defined LINUX struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); struct tm *current_time = localtime(&tv.tv_sec); sprintf(pszFormatTime, "%04d-%02d-%02d %02d:%02d:%02d.%03d", current_time->tm_year + 1900, current_time->tm_mon + 1, current_time->tm_mday, current_time->tm_hour, current_time->tm_min, current_time->tm_sec, tv.tv_usec / 1000); #else SYSTEMTIME sys_time; GetLocalTime(&sys_time); #if _MSC_VER sprintf_s(pszFormatTime, FORMAT_TIME_SIZE, "%04d-%02d-%02d %02d:%02d:%02d.%03d", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds); #else sprintf(pszFormatTime, "%04d-%02d-%02d %02d:%02d:%02d.%03d", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds); #endif #endif return pszFormatTime; } void LogFormat(const char *pszFileName, const int nLine, LogLevel Level, const char *Format, ...) { int ret = 0; char *pszDescribeInfo = NewBuf(LOG_MAX); MY_VA_LIST ap; va_start(ap, Format); #if defined __GNUC__ || defined LINUX ret = vsnprintf(pszDescribeInfo, LOG_MAX, Format, ap); #else #if _MSC_VER ret = _vsnprintf_s(pszDescribeInfo, LOG_MAX, _TRUNCATE, Format, ap); #else ret = _vsnprintf(pszDescribeInfo, LOG_MAX, Format, ap); #endif #endif va_end(ap); if ((LOG_MAX <= ret) || (0 > ret)) { DeleteBuf(&pszDescribeInfo); return; } // 组装日志,[时间][等级][文件名(行数)][自定义字符串] char *pszLog = NewBuf(LOG_MAX); char *pszTime = GetTime(); #if defined __GNUC__ || defined LINUX ret = sprintf(pszLog, "[%s][%s][%s(%d)][%s]", pszTime, g_LogLevel[Level].c_str(), pszFileName, nLine, pszDescribeInfo); #else #if _MSC_VER ret = sprintf_s(pszLog, LOG_MAX, "[%s][%s][%s(%d)][%s]", pszTime, g_LogLevel[Level].c_str(), pszFileName, nLine, pszDescribeInfo); #else ret = sprintf(pszLog, "[%s][%s][%s(%d)][%s]", pszTime, g_LogLevel[Level].c_str(), pszFileName, nLine, pszDescribeInfo); #endif #endif // 日志默认输出到控制台,用户可以自行修改 printf("%s\n", pszLog); DeleteBuf(&pszDescribeInfo); DeleteBuf(&pszLog); DeleteBuf(&pszTime); }
好了这篇文章就介绍到这,需要的朋友可以参考一下。