注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 Exchange服务器系列课程之..
 帮助

一个简单的linux下写日志的类


2008-07-22 10:20:21
 标签:c++ linux   [推送到技术圈]

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://j3com.blog.51cto.com/404571/88904
/*
*
* Copyright (c) 2008,  
* All rights reserved.
*  
* 文件名称: cxxlog2.h
* 文件标识: CT-CXXLOG-1.0-A
* 摘    要: 一个简单的写日志的类
*
* 原 版 本:1.0
* 作    者:j3com <jujianjun@gmail.com>
* 完成日期: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

本文出自 “水滴石穿” 博客,请务必保留此出处http://j3com.blog.51cto.com/404571/88904



上一篇 冷漠  下一篇 爱&情



    文章评论
 
 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: