问题描述
实现一个简单的基于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<10; iLoopFlag++)
{
_snprintf(szLogContent, sizeof(szLogContent)-1, "The value is: %d", iLoopFlag);
WriteLogFile(LOG_INFO, szLogContent);
}
return 0; // main函数执行成功返回0
}
/**********************************************************************
* 功能描述: 将内容写到日志文件中
* 输入参数: iLogLevel-日志等级
*pszContent-每条日志的具体内容
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -------------------------------------------------------------------
* 20150225 V1.0 Zhou Zhaoxiong 创建
********************************************************************/
void WriteLogFile(UINT32 iLogLevel, UINT8 *pszContent)
{
FILE *fp = NULL;
UINT8 szLogContent[2048] = {0};
UINT8 szTimeStr[128] = {0};
if (pszContent == NULL)
{
return;
}
// 过滤日志等级
if (iLogLevel > 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,欢迎关注!)