易网时代-编程资源站
Welcome
微信登录
编程资源
图片资源库
蚂蚁家优选
PDF转换器
软件资源
软件开发
、
小程序制作
、
系统集成与运维
、
空间租用
、
硬件开发
、
视频监控
、
技术咨询与支持
——联系电话:0311-88999002/88999003
首页
/
操作系统
/
Linux
/
C语言实现简单的分级别写日志程序
/************************************************************************/
/*
* 文件名称:write_log.cpp
* 摘 要:此文件实现了普通WINDOWS程序中的日志功能
* 主要有以下特点:
* 1. 根据日期创建日志文件目录,每天的日志分别存放在不同的日志目录中;
* 2. 日志内容分三种类型,根据不同需要,写不同的日志类型的日志文件,
* 方便通过日志定位、分析问题;
* 3. 函数经过比较好的封装,便于复用;
* 待改进点:
* 1. 为了方便,日志内容打印时使用了time函数,其精确度较低;
* 2. 可将这些函数封装为一个日志类,或者动态库,使其更通用;
* 3. 没有考虑跨平台情景,目前只使用于WINDOWS下
* 4. 日志文件内容还可进一步改进,比如打印出当前文件名与行号,使用日志功能
* 更加实用;
*
* 当前版本:1.0
* 作 者:duanyongxing
* 完成日期:2009年10月11日
*/
/************************************************************************/
#ifndef __WRITELOG_H__
#define __WRITELOG_H__
#include "stdafx.h"
#include <time.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <windows.h>
#define _LOG_WRITE_STATE_ 1 /* 条件编译开关,1:写日志,0:不写日志 */
#define LOG_SUCCESS (0)
#define LOG_FAILED (-1)
#define LOG_BOOL_TRUE (1)
#define LOG_BOOL_FALSE (0)
#define DWORD_NULL (0xFFFFFFFF)
#define MAX_LOGTEXT_LEN (2048) /* 每行日志的最大长度*/
#define MAX_FILE_PATH (255) /* 日志文件路径的最大长度*/
#define MAX_LOG_FILE_SIZE (512 * 1024) /* 日志文件内容的最大长度*/
#define MAX_LOG_FILE_NAME_LEN (256) /* 日志文件名的最大长度*/
#define LOG_TYPE_INFO 0 /* 日志类型: 信息类型*/
#define LOG_TYPE_ERROR 1 /* 日志类型: 错误类型*/
#define LOG_TYPE_SYSTEM 2 /* 日志类型: 系统类型*/
#define TEST_CASE_MAX_FILE_LEN (1024) /* 测试函数中文件内容最大长度*/
const
char
g_LogRootPath[] =
"C://My_APPLOG"
;
/*日志文件根路径,由用户指定*/
#pragma pack(push, 1)
typedef
struct
tagLOG_DATA
/* 日志内容结构体*/
{
char
strDate[11];
/* 日期:格式为如:2009-10-11*/
char
strTime[9];
/* 时间:格式为如:16:10:57*/
unsigned
int
iType;
/* 日志类型:3种:INFO(0)/ERROR(1)/SYSTEM(2)*/
char
strText[MAX_LOGTEXT_LEN];
/*日志内容*/
}LOG_DATA, *LPLOG_DATA;
#pragma pack(pop)
int
Create_LogDir(
const
char
*pStrPath);
int
Create_LogFile(
const
char
*pStrFile,
int
iPos);
int
IsFileExist(
const
char
*pStrFile);
int
GetLogPath(
char
*pStrPath);
DWORD
GetFileLenth(
const
char
*pFile);
int
Write_Log_Text(LPLOG_DATA lpLogData);
void
Write_Log(unsigned
int
uiLogType,
char
*pstrFmt, ...);
void
TestLogCase_One();
int
main(
int
argc,
char
* argv[])
{
Write_Log(LOG_TYPE_SYSTEM,
"Program begin."
);
TestLogCase_One();
Write_Log(LOG_TYPE_SYSTEM,
"Program end."
);
return
0;
}
/*********************************************************************
* 函数名称:void TestLogCase_One()
* 说明:简单的测试函数,读文件
* 调用者:main
* 输入参数:
* 无
* 输出参数:
* 无
* 返回值:
* void --
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
void
TestLogCase_One()
{
FILE
*pFile = NULL;
char
*pFieldContent = NULL;
char
szFileName[] =
"test_case.txt"
;
pFieldContent = (
char
*)malloc(TEST_CASE_MAX_FILE_LEN);
if
(NULL == pFieldContent)
{
Write_Log(LOG_TYPE_ERROR,
"malloc memory failed,program exit!"
);
return
;
}
memset(pFieldContent, 0, TEST_CASE_MAX_FILE_LEN);
Write_Log(LOG_TYPE_INFO,
"malloc memory for pFiled successful,memory size is: %ld"
,
TEST_CASE_MAX_FILE_LEN);
pFile = fopen(szFileName,
"r"
);
if
(NULL == pFile)
{
fprintf(stderr,
"open file failed."
);
Write_Log(LOG_TYPE_ERROR,
"Open file %s failed. program exit!"
, szFileName);
return
;
}
Write_Log(LOG_TYPE_INFO,
"Open file %s successful."
, szFileName);
fread(pFieldContent, 1, TEST_CASE_MAX_FILE_LEN, pFile);
pFieldContent[TEST_CASE_MAX_FILE_LEN -1] =
"/0"
;
fclose(pFile);
printf(
"The file %s content is: /n%s/n"
, szFileName, pFieldContent);
Write_Log(LOG_TYPE_INFO,
"The file %s content is: /n%s/n"
, szFileName, pFieldContent);
}
/*********************************************************************
* 函数名称:void Write_Log(unsigned int uiLogType, char *pstrFmt, ...)
* 说明:日志写函数,支持变长参数
* 调用者:任何需要写日志的地方
* 输入参数:
* unsigned iType -- 日志类别
* char *pstrFmt -- 日志内容
* ... -- 变长参数
* 输出参数:
* 无
* 返回值:
* void --
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
void
Write_Log(unsigned
int
uiLogType,
char
*pstrFmt, ...)
{
#if _LOG_WRITE_STATE_ /* 写日志与否的编译开关*/
LOG_DATA data;
time_t
curTime;
struct
tm
*mt;
va_list
v1;
memset(&data, 0,
sizeof
(LOG_DATA));
va_start(v1, pstrFmt);
_vsnprintf(data.strText, MAX_LOGTEXT_LEN, pstrFmt, v1);
va_end(v1);
data.iType = uiLogType;
curTime = time(NULL);
mt = localtime(&curTime);
strftime(data.strDate,
sizeof
(data.strDate),
"%Y-%m-%d"
, mt);
strftime(data.strTime,
sizeof
(data.strTime),
"%H:%M:%S"
, mt);
Write_Log_Text(&data);
#endif _LOG_WRITE_STATE_
}
/*********************************************************************
* 函数名称:int GetLogPath(char *pStrPath)
* 说明:获取日志文件路径
* 调用者:Write_Log_Text
* 输入参数:
* 无
* 输出参数:
* char *pStrPath
* 返回值:
* int -- LOG_FAILED: 失败
* -- LOG_SUCCESS: 成功
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
GetLogPath(
char
*pStrPath)
{
if
(NULL == pStrPath)
{
return
LOG_FAILED;
}
int
iRet = 0;
time_t
curTime = time(NULL);
struct
tm
*mt = localtime(&curTime);
/* 根据日期组成文件夹名称*/
sprintf(pStrPath,
"%s//%d%02d%02d"
, g_LogRootPath, mt->tm_year + 1900,
mt->tm_mon + 1, mt->tm_mday);
iRet = Create_LogDir(pStrPath);
return
iRet;
}
/*********************************************************************
* 函数名称:int GetLogFileName(int iLogType, const char *pStrPath, char *pStrName)
* 说明:获取日志文件名
* 调用者:Write_Log_Text
* 输入参数:
* int iLogType -- 日志类型 3种:INFO(0)/ERROR(1)/SYSTEM(2)
* const char *pStrPath -- 日志路径 由GetLogPath得到
* 输出参数:
* char *pStrName -- 日志文件名
* 返回值:
* int -- LOG_FAILED: 失败
* -- LOG_SUCCESS: 成功
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
GetLogFileName(
int
iLogType,
const
char
*pStrPath,
char
*pStrName)
{
if
(NULL == pStrPath)
{
return
LOG_FAILED;
}
char
szLogName[MAX_FILE_PATH];
FILE
*pFile = NULL;
memset(szLogName, 0, MAX_FILE_PATH);
switch
(iLogType)
{
case
LOG_TYPE_INFO:
sprintf(szLogName,
"%s//app_info"
, pStrPath);
break
;
case
LOG_TYPE_ERROR:
sprintf(szLogName,
"%s//app_error"
, pStrPath);
break
;
case
LOG_TYPE_SYSTEM:
sprintf(szLogName,
"%s//app_system"
, pStrPath);
break
;
default
:
return
LOG_FAILED;
break
;
}
strcat(szLogName,
".log"
);
if
(IsFileExist(szLogName))
{
/* 如果文件长度大于指定的最大长度,重新创建一文件,覆盖原文件*/
if
((
int
)GetFileLenth(szLogName) + 256 >= MAX_LOG_FILE_SIZE)
{
Create_LogFile(szLogName, 0);
}
}
else
{
Create_LogFile(szLogName, 0);
}
sprintf(pStrName,
"%s"
, szLogName);
return
LOG_SUCCESS;
}
/*********************************************************************
* 函数名称:int Create_LogDir(const char *pStrPath)
* 说明:创建日志存放路径
* 调用者:GetLogPath
* 输入参数:
* const char *pStrPath --用户指定的根路径
* 输出参数:
* 无
* 返回值:
* int -- LOG_FAILED: 失败
* -- LOG_SUCCESS: 成功
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
Create_LogDir(
const
char
*pStrPath)
{
if
(NULL == pStrPath)
{
return
LOG_FAILED;
}
int
iRet = 0;
char
szSub[MAX_FILE_PATH];
char
*pSub = NULL;
int
iIndex = 0;
int
iLen = 0;
int
bFind = 0;
memset(szSub, 0,
sizeof
(MAX_FILE_PATH));
/* 逐层创建目录*/
while
(1)
{
pSub = strchr(pStrPath + iLen,
"//"
);
if
(NULL == pSub)
{
if
(iLen == 0)
{
return
LOG_FAILED;
}
iRet = CreateDirectory(pStrPath, NULL);
if
(0 == iRet)
{
iRet = GetLastError();
if
(ERROR_ALREADY_EXISTS == iRet)
{
return
LOG_SUCCESS;
}
return
LOG_FAILED;
}
return
LOG_SUCCESS;
}
else
{
if
(!bFind)
{
bFind = 1;
}
else
{
memset(szSub, 0,
sizeof
(szSub));
strncpy(szSub, pStrPath, pSub - pStrPath);
CreateDirectory(szSub, NULL);
}
iLen = pSub - pStrPath + 1;
}
}
return
LOG_SUCCESS;
}
/*********************************************************************
* 函数名称:int Create_LogFile(const char *pStrFile, int iPos)
* 说明:创建日志文件
* 调用者:GetLogFileName
* 输入参数:
* const char *pStrFile --文件名
* int iPos --文件指针位置
* 输出参数:
* 无
* 返回值:
* int -- LOG_FAILED: 失败
* -- LOG_SUCCESS: 成功
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
Create_LogFile(
const
char
*pStrFile,
int
iPos)
{
HANDLE
hd = 0;
int
iRet = 0;
if
(NULL == pStrFile)
{
return
LOG_FAILED;
}
hd = CreateFile(pStrFile,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if
(INVALID_HANDLE_VALUE == hd)
{
return
LOG_FAILED;
}
if
(DWORD_NULL == SetFilePointer(hd, iPos, NULL, FILE_BEGIN))
{
return
LOG_FAILED;
}
iRet = SetEndOfFile(hd);
CloseHandle(hd);
return
iRet;
}
/*********************************************************************
* 函数名称:int IsFileExist(const char *pStrFile)
* 说明:判断指定的文件是否存在
* 调用者:GetLogFileName
* 输入参数:
* const char *pStrFile --文件名
* 输出参数:
* 无
* 返回值:
* int -- LOG_BOOL_FALSE: 不存在
* -- LOG_BOOL_TRUE: 存在
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
IsFileExist(
const
char
*pStrFile)
{
int
iLen = 0;
WIN32_FIND_DATA finddata;
memset(&finddata, 0,
sizeof
(WIN32_FIND_DATA));
HANDLE
hd = FindFirstFile(pStrFile, &finddata);
if
(INVALID_HANDLE_VALUE == hd)
{
DWORD
dwRet = GetLastError();
if
(ERROR_FILE_NOT_FOUND == dwRet || ERROR_PATH_NOT_FOUND == dwRet)
{
return
LOG_BOOL_FALSE;
}
}
FindClose(hd);
return
LOG_BOOL_TRUE;
}
/*********************************************************************
* 函数名称:DWORD GetFileLenth(const char *pFile)
* 说明:判断指定的文件大小
* 调用者:GetLogFileName
* 输入参数:
* const char *pFile --文件名
* 输出参数:
* 无
* 返回值:
* DWORD -- 文件大小
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
DWORD
GetFileLenth(
const
char
*pFile)
{
WIN32_FIND_DATA buff;
HANDLE
hd = NULL;
memset(&buff, 0,
sizeof
(WIN32_FIND_DATA));
hd = FindFirstFile(pFile, &buff);
FindClose(hd);
return
(buff.nFileSizeHigh * MAXDWORD) + buff.nFileSizeLow;
}
/*********************************************************************
* 函数名称:int Write_Log_Text(LPLOG_DATA lpLogData)
* 说明:写日志内容
* 调用者:Write_Log
* 输入参数:
* LPLOG_DATA lpLogData --日志内容结构体量
* 输出参数:
* 无
* 返回值:
* int -- LOG_FAILED: 失败
* -- LOG_SUCCESS: 成功
* 作者: duanyongxing
* 时间 : 2009-10-11
*********************************************************************/
int
Write_Log_Text(LPLOG_DATA lpLogData)
{
char
szFilePath[MAX_FILE_PATH];
char
szFileName[MAX_LOG_FILE_NAME_LEN];
FILE
*pFile = NULL;
char
szLogText[MAX_LOGTEXT_LEN];
memset(szFilePath, 0, MAX_FILE_PATH);
memset(szFileName, 0, MAX_LOG_FILE_NAME_LEN);
memset(szLogText, 0, MAX_LOGTEXT_LEN);
GetLogPath(szFilePath);
GetLogFileName(lpLogData->iType, szFilePath, szFileName);
pFile = fopen(szFileName,
"a+"
);
if
(NULL == pFile)
{
return
LOG_FAILED;
}
sprintf(szLogText,
"%s %s %s/n"
, lpLogData->strDate, lpLogData->strTime,
lpLogData->strText);
fwrite(szLogText, 1, strlen(szLogText), pFile);
fclose(pFile);
return
LOG_SUCCESS;
}
收藏该网址
版权所有©石家庄振强科技有限公司2024
冀ICP备08103738号-5
网站地图