C语言Log输出收藏(转)

来源:互联网 发布:像韩国人的淘宝模特 编辑:程序博客网 时间:2024/06/05 09:11

在网上找了好多自己写的轮子,最终还是非常喜欢这一款。

很简洁,基本功能也都可以满足。

原作者的文章http://blog.csdn.net/dyx1024/article/details/4720484

因为我在Unicode编译的,因此,作者的代码可能有些地方需要修改一下。

另外,根据自身的需要,对输出位置等下哦功能做了一点修改。

////////////////////////////////////////////////////////////////////Descript: common definition and function.//  Author: guowemyan//    Date:2013.12.17//////////////////////////////////////////////////////////////////#ifndef __WRITELOG_H__   #define __WRITELOG_H__   #include <string>#include <iostream>#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)   /* 测试函数中文件内容最大长度*/   #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)  void Write_Log(unsigned int uiLogType, char *pstrFmt, ...);  #endif //__WRITELOG_H__   

/* * 文件名称:write_log.cpp * 摘    要:此文件实现了普通WINDOWS程序中的日志功能 *           主要有以下特点: *           1. 根据日期创建日志文件目录,每天的日志分别存放在不同的日志目录中; *           2. 日志内容分三种类型,根据不同需要,写不同的日志类型的日志文件, *              方便通过日志定位、分析问题; *           3. 函数经过比较好的封装,便于复用; *           待改进点: *           1. 为了方便,日志内容打印时使用了time函数,其精确度较低; *           2. 可将这些函数封装为一个日志类,或者动态库,使其更通用; *           3. 没有考虑跨平台情景,目前只使用于WINDOWS下 *           4. 日志文件内容还可进一步改进,比如打印出当前文件名与行号,使用日志功能 *              更加实用; * * 当前版本:1.0 * 作    者:duanyongxing  * 完成日期:2009年10月11日 */                                                                       /************************************************************************/  #include "stdafx.h"   #include <time.h>   #include <memory.h>   #include <stdio.h>   #include <stdlib.h>    #include <stdarg.h>   #include <windows.h>   #include "log.h"const char g_LogRootPath[] = "C://My_APPLOG"; /*日志文件根路径,由用户指定*/  const char g_LogLevelStr[][10] = {"INFO  ", "ERROR ", "SYSTEM"};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 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);  sprintf(szLogName, "%s//TestParser", pStrPath); /*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 = (char *)strchr(pStrPath + iLen, '//');  if(NULL == pSub)  {  if(iLen == 0)  {  return LOG_FAILED;  }  iRet = CreateDirectoryA(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);  CreateDirectoryA(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 = CreateFileA(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));  WCHAR szWcharStrFile[260] = _T("\0");MultiByteToWideChar(CP_ACP, 0, pStrFile, strlen(pStrFile), szWcharStrFile, sizeof(szWcharStrFile));HANDLE hd = FindFirstFile(szWcharStrFile, &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));  WCHAR szWcharFile[260] = _T("\0");MultiByteToWideChar(CP_ACP, 0, pFile, strlen(pFile), szWcharFile, sizeof(szWcharFile));hd = FindFirstFile(szWcharFile, &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 %s\n", g_LogLevelStr[lpLogData->iType], lpLogData->strDate, lpLogData->strTime, lpLogData->strText);  fwrite(szLogText, 1, strlen(szLogText), pFile);  fclose(pFile);  return LOG_SUCCESS;  }  


0 0
原创粉丝点击