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
- C语言Log输出收藏(转)
- 在C语言代码中输出Log
- Android NDK :在 C语言代码中输出Log
- Android NDK :在 C语言代码中输出Log
- C语言打印Log
- linux c 编程 log输出
- Android NDK :在 C语言代码中输出Log 法—
- log ( ) 【C语言库函数源代码】
- C语言对数函数log
- C语言Log记录调试
- C语言如何打印LOG
- [收藏]C语言格式化字符串
- log日志:简单的log日志输出(C++)
- c 将log输出到文件
- Android C 层如何输出log
- paho c客户端如何输出log
- 礼拜四log~js控制台输出 & c:forEach
- 在C代码中输出LOG
- iOS开发-iOS7后台的运行机制
- POJ 2243 Knight Moves
- 利用pycharm的Deployment功能映射本地和远程代码(同步开发)
- 继承Application实现Android数据共享
- 搭建跨订阅的虚拟网络到虚拟网络
- C语言Log输出收藏(转)
- UFOs(树状数组)
- 经纬财富:菏泽如何稳健做非农
- 常用 U-boot命令详解(转载)
- Android 中的Context (Application Context 和Activity Context)
- 链表实现的堆栈程序(仅供自己学习使用)
- python的函数、模块、包
- sharepoint 2013 更改搜索服务器配置
- 将git的变更merge到svn或将svn的变更merge到git.