欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++简单日志类文件

程序员文章站 2022-06-03 10:01:33
...

日志

Log 头文件

#ifndef LOGGER_H
#define LOGGER_H

#define LOG_FILE "Logger.log"

enum LOG_LEVEL {
    LOG_DEBUG=0, //调试
    LOG_INFO, //一般日志
    LOG_WARN, //警告
    LOG_ERROR //错误
};

enum LOG_MODE {
    UNIFORM_LOG, //用统一文件名
    DAYLY_LOG,   //按日生成日志 znjz-20170906.log
    MONTHLY_LOG, //按月生成日志 znjz-2017-09.log
    YEARLY_LOG   //按年生成日志
};

extern int FmtWrite(int fd, const char *fmt, ...);//将格式化的内容写入到文件

extern int GetLastError();

class Logger
{
    int fd;
    char filePrefix[16];
    int mode; //1-按天生成日志,2-按月生成日志
    int logLevel;
public:
    Logger();
    /**构造函数
     * logFile - 日志文件名前缀,按日生成的日志文件最后形式为:Pag20140618.log
     *           按月生成的日志文件名为:Pag201406.log
     * m - 日志文件的保存模式,1-按天生成,2-按月生成
     * lev - 日志级别,当级别高于此值时才写入日志
     */
    Logger(const char *logFilePre, int m, int lev);

    /** 析构函数
     */
    ~Logger();

    /**
     * 日志信息:时间,模块名称,日志级别,日志内容
     */
    bool Log(const char *modName, int level, const char *fmt, ...);
};
#endif

Log cpp文件

#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "Log.h"

#define MAX_LOG_LENGTH 1024

Logger::Logger()
{
    fd = -1;
}

Logger::~Logger()
{
    if(fd >=0) {
        close(fd);
    }
    fd = -1;
}

Logger::Logger(const char *logFilePre, int m, int lev)
{
    fd = -1;
    logLevel = lev;
    memset(filePrefix, 0, sizeof(filePrefix));
    strncpy(filePrefix, logFilePre, sizeof(filePrefix)-1);
    mode = m;
}

bool Logger::Log(const char *modName, int level, const char *fmt, ...) 
{
    int len;
    va_list ap;
    char *line;
    int fd;
    char filename[128];
    struct tm tm;
    time_t t;
    static const char *levelStr[] = {"DEBUG", "INFO", "WARN", "ERROR"};

    t = time(NULL);
    localtime_r(&t, &tm);

    len = snprintf(line, MAX_LOG_LENGTH,"[%04d-%02d-%02d %02d:%2d:%2d][%s][%s]:",
            tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour,
            tm.tm_min, tm.tm_sec, modName, levelStr[level]);

     //根据日志记录模式,判断是否已是新的一天或新的一个月,若是,则需要根据情况关闭文件再创建新的文件
    //先判断文件是否已打开,未打开则打开文件
    if(fd  == -1) {
        //根据模式确定打开的文件名格式,追加模式打开
        switch(this->mode) {
        case UNIFORM_LOG:
            sprintf(filename, "./logs/%s", LOG_FILE);
            break;
        case DAILY_LOG:
            sprintf(filename, "./logs/%s_%04d%02d%02d.log",  this->filePrefix, tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
            break;

        }
        if((fd = open(filename, O_CREAT|O_APPEND|O_WRONLY, 0666)) < 0) {
            perror("open");
            return false;
        }
    }
    line = (char *)malloc(MAX_LOG_LENGTH+1);
    if(line == NULL) {
        close(fd);
        return -1;
    }

    va_start(ap, fmt);
    len = vsnprintf(line+len, MAX_LOG_LENGTH-len, fmt, ap);
    va_end( ap );


    write(fd, line, strlen(line));

    free(line);

    return true;
}