/************************************************************************/ /* * 文件名称: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; }
简单的分级别写日志程序
转载于:https://www.cnblogs.com/dyx1024/archive/2009/10/23/2556812.html
相关文章:

达内——java变量
package xx;//为class文件分目录 import xx.xx//导入包中的类 public class 类名{ public static void main(String args[]){ } } 准备工作: jdk jre jvm gc idea pi 配置环境变量 变量名支持字母,数字,_和$,但是数字不能开头&…

JSON Web Tokens测试工具
JSON Web Tokens官方提供测试工具https://jwt.io某些静态资料需要链接google、twitter服务器,被墙无法访问。现在提供可以方法测试工具http://hingtai.cn:8000/转载于:https://www.cnblogs.com/birdstudio/p/7985617.html

oracle 分页写法
select * from (select ROWNUM RN ,TT.* from ( select * from YQ_FEED_BACK_MESSAGE WHERE MODEL_TYPE 3 AND FEED_BACK_TYPE4 order by FEED_BACK_DATE DESC)TT where rownum<5 )where RN >0

给GRUB添加新的项目
安装了win10,然后又安装了manjaro,最后又安装了Ubuntu。开机默认就是进入的Ubuntu的grub,然而我比较喜欢manjaro的grub主题。在bios中设置manjaro的引导为默认引导,但是此时manjaro的grub没有Ubuntu,进入到manjaro系统…

Netapp存储基础之WAFL, NVRAM, RAID, SnapShot
此章节是重点之重点。先讲基本概念。WAFL的全称是Write Anywhere File Layout. 从类似于其它UNIX的文件系统比如Berkeley Fast File System (FFS) 和 TransArc Episode file system. 它的核心理念是"文件任意地方写"。先说普通的文件系统,是由inode和data…

读取本地照片 以流的形式进行显示
获取到前端传来的文件名称,到相应的文件中去读取,通过流的形式写到响应体中。 /*** 显示图片 * getFeedBackPicture.do?picName* return*/RequestMapping(value"/viewPhoto/{photopath}")public void getFeedBackPicture(HttpServletRespons…

如何轻松搞定机构资格准入?
银联的“资格入网”虽涉及环节庞杂,但杂而有序,初次接触银联的机构极有可能不知道先从哪一步骤开始,很多用户甚至不知道该怎么填写材料,所以我整理了一份详细的入网流程,以供大家参考,希望能帮助到大家~ 入…

eclipse CreateProcess error=87 的解决办法
有的说是 ClassPath过长,有的说是Eclipse插件导致最后 在这里得到解决啦http://code.google.com/p/googleappengine/issues/detail?id1862In C:\google\appengine-java-sdk-1.3.1\config\user\ant-macros.xmlChange line 102from<fileset dir"{war}/WEB-IN…

学习javascript 非常好的博客
这个大牛写的非常好!!推荐一下 http://www.cnblogs.com/xiaohuochai/tag/javascript%E6%80%BB%E7%BB%93/default.html?page8 小火柴的蓝色理想 转载于:https://www.cnblogs.com/oxspirt/p/7987342.html

Flex自定义组件
项目中需要用到如下一个效果。下图中五个圆代表一个五孔的梅花管。客户在后台操作时需要编辑梅花管的每个子孔占用情况。客户的要求是:点击某一个孔,小孔变黑,表明此孔被占用;再次点击,则小孔再变成透明圆形࿰…

解决在SQL Server 2000的存储过程不能调试
本机上: 控制面板—>管理工具—>服务—>MSSQL(默认的ID)—>属性—>登陆—>选一个Windows帐户,填写密码,再重新启动SQL Server 2000就可以调试存储过程了。 看一看sql数据库的版本,如果是kf版则不能进…
springboot打成jar后获取classpath下的文件
直接上代码 JAR包用这个 //获取容器资源解析器ResourcePatternResolver resolver new PathMatchingResourcePatternResolver();// 获取远程服务器IP和端口try {//获取所有匹配的文件Resource[] resources resolver.getResources("static/images/faceSearch/*.*"…

thymeleaf : input/select/radio回显
thymeleaf中不用自己去写checked"checked" selected"selected"这种代码,他自己会选。 input <input type"text" class"form-control1" id"name" name"name" th:value"${user.name}"> …

Spark MLlib之使用Breeze操作矩阵向量
这下面的练习中,需要自己将spark的jar包 添加进来。 1.spark Mlib 底层使用的向量、矩阵运算使用了Breeze库。 scalaNLP 是一套 机器学习和数值技算的库。它主要是关于科学技术(sc)、机器学习(ML)和自然语言处理&#…

兄弟们,TechEd见!
马上就要TechEd啦!11月6日到11月7日,在北京举办TechEd,嘿嘿,那就是中国最大的微软技术庙会!盆盆是在2005年时第一次参加TechEd的,当时拿的是MVP的赠票。啥都不懂,就好比刘姥姥进了大观园&#x…

Java - 框架之 SpringBoot 攻略day01
Spring-Boot 攻略 day01 spring-boot 一. 基本配置加运行 1. 导入配置文件(pom.xml 文件中) <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1…

关于 RMAN 备份 数据块 一致性的讨论
今天和 杭州恒生 的一个朋友讨论一个RMAN 在备份时数据块一致性的问题。 关于RMAN 的备份原理参考blog: RMAN 系列(一)---- RMAN 体系结构概述 http://blog.csdn.net/tianlesoftware/archive/2010/06/09/5659701.aspx 先看官方文档上的一段话…

常用git命令
常用 Git 命令清单。专用名词的译名如下。半支烟 Workspace:工作区Index / Stage:暂存区Repository:仓库区(或本地仓库)Remote:远程仓库一、新建代码库 # 在当前目录新建一个Git代码库 $ git init# 新建一个…
springboot 读取配置文件内容的几种方式
1 使用 Environment 进行读取 env.getProperty("配置文件中的值") 2 使用注解的方式 PropertySource("classpath:application.properties") // 获取属性文件 //将其注解到类上 获取属性值 Value("${pictureSearchDemo.apiUrl}") // 获取属性…

Ubuntu9.10使用windows的字体的方法!
使用Ubuntu9.10已经有好几天了,安装字体算是我遇到的比较头疼的一件事,原本按照Ubuntu9.04的方法操作,发现无法使用windows中的字体,换了好几个方法,最终找打了解决方法,过程如下:1、新建一个文…

jmeter笔记(8)--关联
关联是jmeter中比较重要的一个点,在测试过程中有些数据是经常发生变化的,要获取这些数据,就需要使用关联,Jmeter可以通过“后置处理器”中的“正则表达式提取器”来处理关联。。 正则表达式提取器 1、在取样器下点击【添加】--【后…

java连接mysql以及增删改查操作
java连接数据库的代码基本是固定的,步骤过程觉得繁琐些,代码记起来对我来说是闹挺。直接上代码: (温馨提醒:你的项目提前导入连接数据库的jar包才有的以下操作 ) 1 class DBConnection{2 3 // 驱动类…
Jrebel 热部署插件的使用和破解
生成GUIDS 的网站:https://www.guidgen.com/ Jrebel 介绍和破解说明:https://www.cnblogs.com/wang1024/p/7211194.html 本地服务器软件,在使用eclipse或者idea 时打开就可以了。链接:百度云链接 密码:buin

微软SCRUM 1.0流程模板在中文版TFS2010上无法创建项目的解决办法(续)
原文: http://www.almnetworks.net/zh-CN/post/2010/08/04/Microsoft-Visual-Studio-Scrum-10-Template-on-Chinese-Version-of-TFS.aspx 经过我的进一步测试,发现以上步骤不能解决这个问题,但是我找到了一个可以暂时保证我们使用SCRUM模板的…

《父亲家书》选:给初为人师的儿子
文飞:离家已二十九天了,可能是年纪大了的缘故,不要说你妈妈,就连我也想念你了!为不影响你工作,我坚持不够一个月“决”不给你去信。这不到期了,就按时给你去信。你上次来信,早已收到…

vue-cli脚手架
安装 全局环境安装,不必要在项目地址下安装:npm install -g vue-cli 卸载 全局卸载:npm uninstall -g vue-cli 查看是否安装成功:vue list 查看vue版本,vue -V 回车,查看vue最新的版本。 使用 进入到编辑器…

JackJson 使用记录
Map<String,Object> map new HashMap();map.put("ssss","sadsad");// 定义JackJson 对象ObjectMapper mapper new ObjectMapper();//将map转换成JSON字符串String image_json mapper.writeValueAsString(map); https://blog.csdn.net/a123demi/art…

APUE 学习笔记 - Chapter 6. System Data File and Infomation
1.密码文件 每个系统都会有一个文件统一记录用户名与密码,通常是/etc/passwd。关于这个文件有:root 的 uin 通常为 0 .文件中的 x为占位符,代表真实的加密密码保存在另外的文件。没有这一列的时候,表示该用户没有设立密码。将用户…

加密工具和unlocker的使用
在我的电脑上,一些不想让人翻看的程序和资料都使用一款《E-钻文件夹加密大师》的伪加密软件来加密。 这个程序只防君子不防小人,真正想看的人还是可以找到方法看的。并且这个软件还有些bug和不方便之处。 我在电脑上编程之前需要对多个代码文件夹进行解密…

第四章:操作列表
第四章:操作列表4.1 遍历整个列表如果名单很长,将包含大量反复的代码。另外,每当名单的长度发生变化时,都必须修改代码。通过for循环,可让Python去处理这些问题1)使用for循环来打印魔术师名单中的所有名字&…