问题描述
实现一个简单的基于Windows的日志系统,要求写入日志文件的内容的样式如下:
[时间]+[文件名]+[日志等级]+日志具体内容
如:
[2015.02.2514:35:13.143][WriteLog.c][INFO]This is a test!
其中,“2015.02.25 14:35:13.143”为当前时间(精确到毫秒),“WriteLog.c”为所打印的日志内容所在的文件名,“INFO”为日志的等级,“This is a test!”为日志的具体内容。
算法流程
图1 程序总体执行流程
图2 写日志操作总体执行流程
C代码实现
/********************************************************************** * 版权所有 (C)2015, Zhou Zhaoxiong。 * * 文件名称:WriteLog.c * 文件标识:无 * 内容摘要:演示日志信息的打印方法 * 其它说明:无 * 当前版本:V1.0 * 作 者:Zhou Zhaoxiong * 完成日期:20150225 * **********************************************************************/ #include#include // 重定义数据类型 typedef signed int INT32; typedef unsigned int UINT32; typedef unsigned char UINT8; // 全局变量 UINT32 g_iLogLevel = 0; // 日志等级 UINT8 g_szLogFile[100] = {0}; // 带路径的日志文件名 // 宏定义 #define LOG_FATAL 0 // 严重错误 #define LOG_ERROR 1 // 一般错误 #define LOG_WARN 2 // 警告 #define LOG_INFO 3 // 一般信息 #define LOG_TRACE 4 // 跟踪信息 #define LOG_DEBUG 5 // 调试信息 #define LOG_ALL 6 // 所有信息 // 函数声明 void WriteLogFile(UINT32 iLogLevel, UINT8 *pszContent); UINT8 *LogLevel(UINT32 iLogLevel); void GetTime(UINT8 *pszTimeStr); INT32 main(); /********************************************************************** * 功能描述:主函数 * 输入参数:无 * 输出参数:无 * 返 回 值:无 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20150225 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 main() { UINT8 szConfigFile[128] = {0}; UINT8 szLogContent[1024] = {0}; UINT8 szLogDir[128] = {0}; UINT32 iLoopFlag = 0; // 获取配置文件全路径(包括文件名) GetCurrentDirectory(sizeof(szConfigFile)-1, szConfigFile); strcat(szConfigFile, "\\"); strcat(szConfigFile, "Config.ini"); // 日志等级 g_iLogLevel = GetPrivateProfileInt("LOG", "LogLevel", 3, szConfigFile); // 日志文件存放目录 GetPrivateProfileString("LOG", "LogDir", "", szLogDir, sizeof(szLogDir), szConfigFile); _snprintf(g_szLogFile, sizeof(g_szLogFile)-1, "%s\\WriteLog.log", szLogDir); // 打印第一条日志 _snprintf(szLogContent, sizeof(szLogContent)-1, "The first log info!"); WriteLogFile(LOG_INFO, szLogContent); // 打印第二条日志 _snprintf(szLogContent, sizeof(szLogContent)-1, "The second log info!"); WriteLogFile(LOG_DEBUG, szLogContent); // 打印0到9的10个数 for (iLoopFlag=0; iLoopFlag g_iLogLevel) { return; } fp = fopen(g_szLogFile, "at+"); // 打开文件, 每次写入的时候在后面追加 if (fp == NULL) { return; } // 写入日志时间 GetTime(szTimeStr); fputs(szTimeStr, fp); // 写入日志内容 // 在原内容中添加日志等级标识 _snprintf(szLogContent, sizeof(szLogContent)-1, "[WriteLog.c][%s]%s\n", LogLevel(iLogLevel), pszContent); fputs(szLogContent, fp); fflush(fp); // 刷新文件 fclose(fp); // 关闭文件 fp = NULL; // 将文件指针置为空 return; } /********************************************************************** * 功能描述: 获取对应的日志等级 * 输入参数: iLogLevel-日志等级 * 输出参数: 无 * 返 回 值: 日志等级信息字符串 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20150225 V1.0 Zhou Zhaoxiong 创建 ********************************************************************/ UINT8 *LogLevel(UINT32 iLogLevel) { switch (iLogLevel) { case LOG_FATAL: { return "FATAL"; } case LOG_ERROR: { return "ERROR"; } case LOG_WARN : { return "WARN"; } case LOG_INFO : { return "INFO"; } case LOG_TRACE: { return "TRACE"; } case LOG_DEBUG: { return "DEBUG"; } case LOG_ALL: { return "ALL"; } default: { return "OTHER"; } } } /********************************************************************** * 功能描述: 获取时间串 * 输入参数: 无 * 输出参数: pszTimeStr-时间串 * 返 回 值: 无 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20150225 V1.0 Zhou Zhaoxiong 创建 ********************************************************************/ void GetTime(UINT8 *pszTimeStr) { SYSTEMTIME tSysTime = {0}; GetLocalTime(&tSysTime); sprintf(pszTimeStr, "[%04d.%02d.%02d %02d:%02d:%02d.%03d]", tSysTime.wYear, tSysTime.wMonth, tSysTime.wDay, tSysTime.wHour, tSysTime.wMinute, tSysTime.wSecond, tSysTime.wMilliseconds); return; }
配置文件内容
配置文件命名为Config.ini,其内容形如:
[LOG]
;LogLevel, 0-Fatal 1-Error 2-Warn 3-Info 4-Trace 5-Debug 6-All
LogLevel=5
;Log dir
LogDir=D:\\Test
其中,“LogLevel”表示日志等级,“LogDir”表示日志文件存放的路径(注意:最后不要用\\结尾)。要根据实际的需要来改变各个配置项的值。
程序说明
(1)本程序直接在VC++中编译运行。
(2)配置文件Config.ini直接放到与WriteLog.c文件同级的工程目录下即可。
(3)通过改变“LogLevel”的配置值,可选择性地打印一些日志信息。
程序运行结果
(1)将“LogLevel”配为3,日志文件的内容如下:
(2)将“LogLevel”配为5,日志文件的内容如下:
可见,程序可以根据配置的日志等级来输出相应的日志信息。
(本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)