一个简单的linux下写日志的类
时间:2009-03-23 来源:sjhf
/* * * Copyright (c) 2008, * All rights reserved. * * 文件名称: cxxlog2.h * 文件标识: CT-CXXLOG-1.0-A * 摘 要: 一个简单的写日志的类 * * 原 版 本:1.0 * 作 者:j3com <[email protected]> * 完成日期:2008-07-21 * */ #ifndef _CXXLOG_H_ #define _CXXLOG_H_ #include <stdio.h> #include <time.h> #include <stddef.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> //设定写日志文件模式: M_DEFAULT-默认普通 M_DAY-按天(每天一个文件) //M_SIZE-按大小(M单位,达到指定大小重命名) enum LOGMODE { M_DEFAULT, M_DAY, M_SIZE }; class Cxxlog { public: //构造方法 //NOTE: f-带路径的日志文件 lm-写日志方式,默认写日志方式为普通方式 //ms-日志文件大小,单位为M,只有lm=M_SIZE时有效 Cxxlog( char * f, LOGMODE lm=M_DEFAULT, int ms=0 ) { fd = -1; strcpy( fileName, f ); logMode=lm; msize=ms; getToday(CREATEDAY); } //析构方法 ~Cxxlog() { closefile(); } //打开文件 //NOTE: 返回 >0 表示成功, 其他 表示失败 int openfile( void ) { if ( fd > 0 ) { return fd; } fd = open( fileName, O_WRONLY|O_APPEND|O_CREAT, 0666 ); if ( fd < 0 ) { printf( "\n\nOpen the file: <%s> error!\n\n", fileName ); } return fd; } //关闭文件 //NOTE: 返回 -1 表示关闭失败, 0 表示成功 int closefile( void ) { if ( fd > -1 ) { return close( fd ); } return 0; } //打印方法 //NOTE: 返回 -1 表示写入失败, 0 表示成功 int print( const char * str ) { if ( !checkLogFile() ) { return -1; } if ( -1 == write(fd,str,strlen(str)) ) { closefile(); openfile(); } return write(fd,str,strlen(str)); } //打印方法 //NOTE: 返回 -1 表示写入失败, 0 表示成功 int print( char * fmt,... ) { if ( !checkLogFile() ) { return -1; } memset(buf, 0, sizeof(buf)); va_list ap; va_start( ap, fmt ); vsprintf( buf, fmt, ap ); va_end ( ap ); if ( -1 == write(fd,buf,strlen(buf)) ) { closefile(); openfile(); } return write(fd,buf,strlen(buf)); } //得到格式化的当前日期和时间 void getFormatTime(char *p) { tick=time(NULL); lt=localtime(&tick); sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d", lt->tm_year+1900,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec); } private: //检测日志文件 //根据日志文件状态以及所设定模式进行检测并调用相应的处理方法 //NOTE: 返回 true 表示成功, false 表示失败 bool checkLogFile() { if ( fd <= 0 ) { //文件没有打开 return (openfile()>0) ? true : false ; } //根据不同的选项做对应操作 switch ( logMode ) { case M_SIZE: return ( 0==check_mode_size() ) ? true : false; case M_DAY: return ( 0==check_mode_day() ) ? true : false; default: return true; } return true; } //指定文件大小模式下的检测方法 //NOTE: 0 成功, 其他 失败 int check_mode_size() { if ( fstat(fd, &logFileStat) < 0 ) { return -1; } int fileSize = (int)logFileStat.st_size; if ( msize*1049000 < fileSize ) { //文件超过定义的文件长度大小,需要将日志文件备份并且新开一个日志文件 char newFileName[125]; char suffix[30]; getMSizeSuffix( suffix ); strcpy(newFileName, fileName); strcat(newFileName,suffix); if ( -1 == closefile() ) { return -1; } if ( -1 == rename(fileName,newFileName) ) { return -1; } if ( 0 > openfile() ) { return -1; } } return 0; } //日期模式下的检测方法 //NOTE: 0 成功, 其他 失败 int check_mode_day() { getToday( TODAY ); if ( strcmp(TODAY,CREATEDAY) !=0 ) { //当前日期和,需要将日志文件备份并且新开一个日志文件 char newFileName[125]; sprintf(newFileName,"%s.%s",fileName,TODAY); if ( -1 == closefile() ) { return -1; } if ( -1 == rename(fileName,newFileName) ) { return -1; } if ( 0 > openfile() ) { return -1; } strcpy(CREATEDAY,TODAY); } return 0; } //得到YYYYDDHH格式的当前日期 void getToday( char * today ) { tick=time(NULL); lt=localtime(&tick); sprintf(today, "%04d%02d%02d", lt->tm_year+1900,lt->tm_mon+1,lt->tm_mday); } //指定文件大小模式下,得到备份的新文件名的后缀 void getMSizeSuffix( char * suffix ) { static int idx; tick=time(NULL); lt=localtime(&tick); sprintf(suffix, ".%04d%02d%02d%02d%02d%02d.%03d", lt->tm_year+1900,lt->tm_mon+1,lt->tm_mday,++idx); } private: int fd; char fileName[100]; //保存日志文件路径 struct tm * lt; time_t tick; char buf[1024]; //规定1次写入日志操作的内容字节数 char TODAY[11]; //当前的YYYYMMDD格式日期 char CREATEDAY[11]; //文件创立时的YYYYMMDD格式日期 LOGMODE logMode; //定义写日志的模式 int msize; //定义M_SIZE写日志模式下的文件大小,单位M struct stat logFileStat; //日志文件状态结构变量 }; #endif |
相关阅读 更多 +