linux c 自定义日志级别,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 

#include 

#include 

#include 

#include 

#include 

#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)   /* 测试函数中文件内容最大长度*/

constcharg_LogRootPath[] ="C://My_APPLOG";/*日志文件根路径,由用户指定*/

#pragma pack(push, 1)

typedefstructtagLOG_DATA/* 日志内容结构体*/

{

charstrDate[11];/* 日期:格式为如:2009-10-11*/

charstrTime[9];/* 时间:格式为如:16:10:57*/

unsignedintiType;/* 日志类型:3种:INFO(0)/ERROR(1)/SYSTEM(2)*/

charstrText[MAX_LOGTEXT_LEN];/*日志内容*/

}LOG_DATA, *LPLOG_DATA;

#pragma pack(pop)

intCreate_LogDir(constchar*pStrPath);

intCreate_LogFile(constchar*pStrFile,intiPos);

intIsFileExist(constchar*pStrFile);

intGetLogPath(char*pStrPath);

DWORDGetFileLenth(constchar*pFile);

intWrite_Log_Text(LPLOG_DATA lpLogData);

voidWrite_Log(unsignedintuiLogType,char*pstrFmt, ...);

voidTestLogCase_One();

intmain(intargc,char* argv[])

{

Write_Log(LOG_TYPE_SYSTEM,"Program begin.");

TestLogCase_One();

Write_Log(LOG_TYPE_SYSTEM,"Program end.");

return0;

}

/*********************************************************************

* 函数名称:void TestLogCase_One()

* 说明:简单的测试函数,读文件

* 调用者:main

* 输入参数:

* 无

* 输出参数:

* 无

* 返回值:

* void  --

* 作者: duanyongxing

* 时间 : 2009-10-11

*********************************************************************/

voidTestLogCase_One()

{

FILE*pFile = NULL;

char*pFieldContent = NULL;

charszFileName[] ="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

*********************************************************************/

voidWrite_Log(unsignedintuiLogType,char*pstrFmt, ...)

{

#if _LOG_WRITE_STATE_   /* 写日志与否的编译开关*/

LOG_DATA data;

time_tcurTime;

structtm*mt;

va_listv1;

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

*********************************************************************/

intGetLogPath(char*pStrPath)

{

if(NULL == pStrPath)

{

returnLOG_FAILED;

}

intiRet = 0;

time_tcurTime = time(NULL);

structtm*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);

returniRet;

}

/*********************************************************************

* 函数名称: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

*********************************************************************/

intGetLogFileName(intiLogType,constchar*pStrPath,char*pStrName)

{

if(NULL == pStrPath)

{

returnLOG_FAILED;

}

charszLogName[MAX_FILE_PATH];

FILE*pFile = NULL;

memset(szLogName, 0, MAX_FILE_PATH);

switch(iLogType)

{

caseLOG_TYPE_INFO:

sprintf(szLogName,"%s//app_info", pStrPath);

break;

caseLOG_TYPE_ERROR:

sprintf(szLogName,"%s//app_error", pStrPath);

break;

caseLOG_TYPE_SYSTEM:

sprintf(szLogName,"%s//app_system", pStrPath);

break;

default:

returnLOG_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);

returnLOG_SUCCESS;

}

/*********************************************************************

* 函数名称:int Create_LogDir(const char *pStrPath)

* 说明:创建日志存放路径

* 调用者:GetLogPath

* 输入参数:

* const char *pStrPath --用户指定的根路径

* 输出参数:

* 无

* 返回值:

* int  -- LOG_FAILED:  失败

*      -- LOG_SUCCESS: 成功

* 作者: duanyongxing

* 时间 : 2009-10-11

*********************************************************************/

intCreate_LogDir(constchar*pStrPath)

{

if(NULL == pStrPath)

{

returnLOG_FAILED;

}

intiRet = 0;

charszSub[MAX_FILE_PATH];

char*pSub = NULL;

intiIndex = 0;

intiLen = 0;

intbFind = 0;

memset(szSub, 0,sizeof(MAX_FILE_PATH));

/* 逐层创建目录*/

while(1)

{

pSub = strchr(pStrPath + iLen,'//');

if(NULL == pSub)

{

if(iLen == 0)

{

returnLOG_FAILED;

}

iRet = CreateDirectory(pStrPath, NULL);

if(0 == iRet)

{

iRet = GetLastError();

if(ERROR_ALREADY_EXISTS == iRet)

{

returnLOG_SUCCESS;

}

returnLOG_FAILED;

}

returnLOG_SUCCESS;

}

else

{

if(!bFind)

{

bFind = 1;

}

else

{

memset(szSub, 0,sizeof(szSub));

strncpy(szSub, pStrPath, pSub - pStrPath);

CreateDirectory(szSub, NULL);

}

iLen = pSub - pStrPath + 1;

}

}

returnLOG_SUCCESS;

}

/*********************************************************************

* 函数名称:int Create_LogFile(const char *pStrFile, int iPos)

* 说明:创建日志文件

* 调用者:GetLogFileName

* 输入参数:

* const char *pStrFile --文件名

* int iPos             --文件指针位置

* 输出参数:

* 无

* 返回值:

* int  -- LOG_FAILED:  失败

*      -- LOG_SUCCESS: 成功

* 作者: duanyongxing

* 时间 : 2009-10-11

*********************************************************************/

intCreate_LogFile(constchar*pStrFile,intiPos)

{

HANDLEhd = 0;

intiRet = 0;

if(NULL == pStrFile)

{

returnLOG_FAILED;

}

hd = CreateFile(pStrFile,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL

);

if(INVALID_HANDLE_VALUE == hd)

{

returnLOG_FAILED;

}

if(DWORD_NULL == SetFilePointer(hd, iPos, NULL, FILE_BEGIN))

{

returnLOG_FAILED;

}

iRet = SetEndOfFile(hd);

CloseHandle(hd);

returniRet;

}

/*********************************************************************

* 函数名称:int IsFileExist(const char *pStrFile)

* 说明:判断指定的文件是否存在

* 调用者:GetLogFileName

* 输入参数:

* const char *pStrFile --文件名

* 输出参数:

* 无

* 返回值:

* int  -- LOG_BOOL_FALSE:  不存在

*      -- LOG_BOOL_TRUE: 存在

* 作者: duanyongxing

* 时间 : 2009-10-11

*********************************************************************/

intIsFileExist(constchar*pStrFile)

{

intiLen = 0;

WIN32_FIND_DATA finddata;

memset(&finddata, 0,sizeof(WIN32_FIND_DATA));

HANDLEhd = FindFirstFile(pStrFile, &finddata);

if(INVALID_HANDLE_VALUE == hd)

{

DWORDdwRet = GetLastError();

if(ERROR_FILE_NOT_FOUND == dwRet || ERROR_PATH_NOT_FOUND == dwRet)

{

returnLOG_BOOL_FALSE;

}

}

FindClose(hd);

returnLOG_BOOL_TRUE;

}

/*********************************************************************

* 函数名称:DWORD GetFileLenth(const char *pFile)

* 说明:判断指定的文件大小

* 调用者:GetLogFileName

* 输入参数:

* const char *pFile --文件名

* 输出参数:

* 无

* 返回值:

* DWORD -- 文件大小

* 作者: duanyongxing

* 时间 : 2009-10-11

*********************************************************************/

DWORDGetFileLenth(constchar*pFile)

{

WIN32_FIND_DATA buff;

HANDLEhd = 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

*********************************************************************/

intWrite_Log_Text(LPLOG_DATA lpLogData)

{

charszFilePath[MAX_FILE_PATH];

charszFileName[MAX_LOG_FILE_NAME_LEN];

FILE*pFile = NULL;

charszLogText[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)

{

returnLOG_FAILED;

}

sprintf(szLogText,"%s %s %s/n", lpLogData->strDate, lpLogData->strTime,

lpLogData->strText);

fwrite(szLogText, 1, strlen(szLogText), pFile);

fclose(pFile);

returnLOG_SUCCESS;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值