/************************************************************************/ /* * 文件名称: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; }
您还没有登录,请您登录后再发表评论
C简单的分级别写日志程序归类.pdf
1.该类自动以当前日期作为日志文件名,格式形...3.该类根据日志级别决定写文件与否,同时也会根据日志级别选择将信息输出到终端方便调试。 4.该类功能比较简单,适用于小体量日志的记录,其他复杂场景请使用成熟的Log库
自己写的log4j的入门程序,对log4j中几种级别的日志输出进行了测试,程序简单易懂
使用 CStaticLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法写日志 调用 CStaticLogger->UnInit(...) 清理日志组件(CStaticLogger 对象析构时也会自动清理日志组件) ...
b) 使用单独线程在后台写日志,不影响工作线程的正常执行 c) 采用批处理方式批量记录日志 Usage: 方法一:(静态加载 Logger DLL) --------------------------------------------------------------------...
用TypeScript编写的真正高度可组合的日志记录实用程序 描述 Zoya是一个高度可组合的日志记录库,用于...具有流级别过滤的多个可配置可写流 简单而最少的语法 用TypeScript编写 内容 安装 纱 yarn add zoya NPM npm i
规模化日志级别机制 字符串插值支持 多个可配置的可写流 简单而最少的语法 可通过package.json全局配置 每个文件和记录器的可覆盖配置 内容 安装 纱 yarn add signale NPM npm install signale 用法 默认记录器 ...
* 简单调用包装dzlog(一个程序默认只用一个分类) * MDC,线程键-值对的表,可以扩展用户自定义的字段 * 自诊断,可以在运行时输出zlog自己的日志和配置状态 * 不依赖其他库,只要是个POSIX系统...
一.项目架构 3 1.技术点扩展和改进 4 2.Asp.Net MVC框架 4 ...1.日志级别 19 2.异常处理(Exception) 19 2.1.SystemException 19 2.2.ApplicationException 19 2.3.异常处理的方法技巧 20 3.日志书写 20
在Android开发过程中,不管是写Demo还是实战项目中,都会打印一些日志用于记录数据,调试来着,Android中的日志工具类是Log,这个类提供了一些方法来打印日志。五个级别,v、d、i、w、e,各有不同的重载。 当谈到...
Logquacious(lq)是Cash App构建的快速简单的日志查看器。 它目前仅支持浏览存储的日志,但是存储/索引后端是可插入的。 如果您有兴趣贡献更多的后端,请打开请求请求! 基本原理 将应用程序日志和系统日志放在...
Microsoft Windows 系统错误代码简单分析: 0000 操作已成功完成。 0001 错误的函数。 0002 系统找不到指定的文件。 0003 系统找不到指定的路径。 0004 系统无法打开文件。 0005 拒绝访问。...
没有这个文件或不在主目录中则不写日志 [log4me] #path,日志的存放目录.必须是主程序目录及子目录. #例子:主程序目录 #path=. #例子:子目录 #path=temp\logs path=logs #level,日志等级,只能是 error,info,debug之一...
第7章 向应用程序中加入Ajax 7.1 组合的技术 7.1.1 语义化XHTML和DOM 7.1.2 JavaScript和XMLHttpRequest对象 7.1.3 XML 7.1.4 一个可重用的对象 7.1.5 Ajax是正确的选择吗 7.2...
##spring-boot留言板 项目的目标 1 使用spring写个简单的留言板 2 尽可能的使用spring的各种配置 项目的具体目标 1 添加留言 ...DONE 2 使用log4j2写日志 1 记录各个级别的日志 2 了解log4j2的基本的
Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证...
本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了6项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮...
同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本...
相关推荐
C简单的分级别写日志程序归类.pdf
1.该类自动以当前日期作为日志文件名,格式形...3.该类根据日志级别决定写文件与否,同时也会根据日志级别选择将信息输出到终端方便调试。 4.该类功能比较简单,适用于小体量日志的记录,其他复杂场景请使用成熟的Log库
自己写的log4j的入门程序,对log4j中几种级别的日志输出进行了测试,程序简单易懂
使用 CStaticLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法写日志 调用 CStaticLogger->UnInit(...) 清理日志组件(CStaticLogger 对象析构时也会自动清理日志组件) ...
b) 使用单独线程在后台写日志,不影响工作线程的正常执行 c) 采用批处理方式批量记录日志 Usage: 方法一:(静态加载 Logger DLL) --------------------------------------------------------------------...
用TypeScript编写的真正高度可组合的日志记录实用程序 描述 Zoya是一个高度可组合的日志记录库,用于...具有流级别过滤的多个可配置可写流 简单而最少的语法 用TypeScript编写 内容 安装 纱 yarn add zoya NPM npm i
规模化日志级别机制 字符串插值支持 多个可配置的可写流 简单而最少的语法 可通过package.json全局配置 每个文件和记录器的可覆盖配置 内容 安装 纱 yarn add signale NPM npm install signale 用法 默认记录器 ...
* 简单调用包装dzlog(一个程序默认只用一个分类) * MDC,线程键-值对的表,可以扩展用户自定义的字段 * 自诊断,可以在运行时输出zlog自己的日志和配置状态 * 不依赖其他库,只要是个POSIX系统...
b) 使用单独线程在后台写日志,不影响工作线程的正常执行 c) 采用批处理方式批量记录日志 Usage: 方法一:(静态加载 Logger DLL) --------------------------------------------------------------------...
一.项目架构 3 1.技术点扩展和改进 4 2.Asp.Net MVC框架 4 ...1.日志级别 19 2.异常处理(Exception) 19 2.1.SystemException 19 2.2.ApplicationException 19 2.3.异常处理的方法技巧 20 3.日志书写 20
在Android开发过程中,不管是写Demo还是实战项目中,都会打印一些日志用于记录数据,调试来着,Android中的日志工具类是Log,这个类提供了一些方法来打印日志。五个级别,v、d、i、w、e,各有不同的重载。 当谈到...
Logquacious(lq)是Cash App构建的快速简单的日志查看器。 它目前仅支持浏览存储的日志,但是存储/索引后端是可插入的。 如果您有兴趣贡献更多的后端,请打开请求请求! 基本原理 将应用程序日志和系统日志放在...
Microsoft Windows 系统错误代码简单分析: 0000 操作已成功完成。 0001 错误的函数。 0002 系统找不到指定的文件。 0003 系统找不到指定的路径。 0004 系统无法打开文件。 0005 拒绝访问。...
没有这个文件或不在主目录中则不写日志 [log4me] #path,日志的存放目录.必须是主程序目录及子目录. #例子:主程序目录 #path=. #例子:子目录 #path=temp\logs path=logs #level,日志等级,只能是 error,info,debug之一...
第7章 向应用程序中加入Ajax 7.1 组合的技术 7.1.1 语义化XHTML和DOM 7.1.2 JavaScript和XMLHttpRequest对象 7.1.3 XML 7.1.4 一个可重用的对象 7.1.5 Ajax是正确的选择吗 7.2...
##spring-boot留言板 项目的目标 1 使用spring写个简单的留言板 2 尽可能的使用spring的各种配置 项目的具体目标 1 添加留言 ...DONE 2 使用log4j2写日志 1 记录各个级别的日志 2 了解log4j2的基本的
Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证...
本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了6项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮...
本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问题时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了6项高级功能。点击其中的“注册系统文件夹中所有dll文件”按钮...
同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本...