• 日志


    背景

    封装日志API供平时代码学习使用,顺便学习一下相关的知识点:

    • 变参函数
    • 时间的格式化输出

    c语言版本

    log.h

    #ifndef _LOG_H_
    #define _LOG_H_
     
    #include <stdarg.h>
    #include <stdio.h>
    #include <time.h>
    #include <string.h>
     
    #define  LOG_DEBUG           0x01
    #define  LOG_INFOR           0x02
    #define  LOG_WARNING         0x03
    #define  LOG_ERROR           0x04
    #define  LOG_FATAL_ERROR     0x05
     
    #define  LOG_DBG(format, ...) 
        WriteLog(LOG_DEBUG, "DEBUG ", __LINE__, __FUNCTION__, __FILE__, format,  ##__VA_ARGS__)
    #define  LOG_INFO(format, ...) 
        WriteLog(LOG_INFOR, "INFO ", __LINE__, __FUNCTION__, __FILE__, format,  ##__VA_ARGS__)
    #define  LOG_WARN(format, ...) 
        WriteLog(LOG_WARNING, "WARN ", __LINE__, __FUNCTION__, __FILE__, format,  ##__VA_ARGS__)
    #define  LOG_ERR(format, ...) 
        WriteLog(LOG_ERROR, "ERR  ", __LINE__, __FUNCTION__, __FILE__, format,  ##__VA_ARGS__)
    #define  LOG_FATAL(format, ...) 
        WriteLog(LOG_FATAL_ERROR, "FATAL", __LINE__, __FUNCTION__, __FILE__, format,  ##__VA_ARGS__)
     
    FILE *log_file;
    int log_level;
     
    int LogInit(const int level, const char *path)
    {
        log_level = level;
        log_file = fopen(path, "a");
        if (NULL == log_file)
        {
            return -1;
        }
    //---行缓冲 setvbuf(log_file, NULL, _IOLBF,
    0); /**/ return 0; } int WriteLog(int v_level,const char *level, int line, const char *func, const char *file, const char * format, ...) { if (log_level > v_level){return -1;} //---文件名,行号,函数名 char log_pos[64] = {0}; sprintf(log_pos, " %s %s:%d [%s] ", level, file, line, func); //---时间戮 char log_time[64] = {0}; time_t t = time(NULL); struct tm ptm; localtime_r(&t, &ptm); sprintf(log_time, "%4d-%02d-%02d %02d:%02d:%02d", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec); //---日志内容 char log_msg[5*1024] = {0}; va_list arg_ptr; va_start(arg_ptr, format); int nWrittenBytes = vsnprintf(log_msg,sizeof(log_msg), format, arg_ptr); if (nWrittenBytes < 0) { perror("vsnprintf"); return -1; } va_end(arg_ptr); //---拼接 char log_output[6*1024] = {0}; strcat(log_output, log_time); strcat(log_output, log_pos); strcat(log_output, log_msg); fprintf(log_file, "%s ", log_output); return nWrittenBytes; } #endif

    测试

    #include "log.h"
     
    int main()
    {
        if(LogInit(LOG_INFOR, "forever.log"))
        {   
            printf("log init failed.
    ");
            return -1; 
        }   
     
        int tmp = 123;
        LOG_DBG("***********");
        LOG_INFO("***********");
        LOG_INFO("%d", tmp);
        LOG_INFO("%s%p", "infor log", &tmp);
        LOG_WARN("%s***%d", "warning log", tmp);
        LOG_ERR("%s   %d", "error log", tmp);
        LOG_FATAL("%s   %d", "fatal error log", tmp);
        return 0;
    }

    日志输出

    [root@localhost]# gcc main.c 
    [root@localhost]# ./a.out
    [root@localhost]# tail -f forever.log 
    2019-05-09 13:40:06  INFO   main.c:13  [main] ***********
    2019-05-09 13:40:06  INFO   main.c:14  [main] 123
    2019-05-09 13:40:06  INFO   main.c:15  [main] infor log0x7ffd443c729c
    2019-05-09 13:40:06  WARN   main.c:16  [main] warning log***123
    2019-05-09 13:40:06  ERR    main.c:17  [main] error log   123
    2019-05-09 13:40:06  FATAL  main.c:18  [main] fatal error log   123

    c++版本

    log.h

    #ifndef _LOG_H_                                                                                                                                                                                                                                                                
    #define _LOG_H_
    
    enum LogLevel {
        ALL = 0,
        INFO,
        WARN,
        ERR 
    };
    
    class LOG {
    
    public:
        static void INFO(const char *msg, ...);
        static void WARN(const char *msg, ...);
        static void ERR(const char *msg, ...);
        static void SetLogLevel(LogLevel level) { logLevel = level; }
    private:
        static void write(const char *msg);
        static LogLevel logLevel;
    };
    
    #endif

    log.cc

    #include "log.h"                                                                                                                                                                                                                                                               
    #include <stdarg.h>
    #include <string.h>
    #include <time.h>
    #include <sys/time.h>
    #include <stdio.h>
    
    LogLevel LOG::logLevel = LogLevel::ALL;
    
    void LOG::write(const char *msg)
    {
        struct timeval tv; 
        struct tm tm_time;
        long mseconds, useconds;
        static char cur_timestr[32] = ""; 
        gettimeofday(&tv, NULL);
        gmtime_r(&tv.tv_sec, &tm_time);
        mseconds = tv.tv_usec / 1000;
        useconds = tv.tv_usec % 1000;
        sprintf(cur_timestr, "%d/%d/%d %d:%d:%d:%ld:%ld", 
                tm_time.tm_year +1900, tm_time.tm_mon, tm_time.tm_mday, 
                tm_time.tm_hour +8, tm_time.tm_min, tm_time.tm_sec, 
                mseconds, useconds);
    
        printf("%s %s", cur_timestr, msg);
    }
    void LOG::INFO(const char *msg, ...)
    {
        if (logLevel > LogLevel::INFO) {return;}
        if (!msg) {return;}
        char pTemp[1024] = { 0 };
        va_list arg_ptr;
        va_start(arg_ptr, msg);
        vsprintf(pTemp + strlen(pTemp), msg, arg_ptr);
        va_end(arg_ptr);
    
        LOG::write(pTemp);
    }
    void LOG::WARN(const char *msg, ...)
    {
        if (logLevel > LogLevel::WARN)
            return;
    
        if (!msg) {return;}
        char pTemp[1024] = { 0 };
        va_list arg_ptr;
        va_start(arg_ptr, msg);
        vsprintf(pTemp + strlen(pTemp), msg, arg_ptr);
        va_end(arg_ptr);
    
        LOG::write(pTemp);
    }
    void LOG::ERR(const char *msg, ...)
    {
        if (!msg) {return;}
        char pTemp[1024] = { 0 };
        va_list arg_ptr;
        va_start(arg_ptr, msg);
        vsprintf(pTemp + strlen(pTemp), msg, arg_ptr);
        va_end(arg_ptr);
    
        LOG::write(pTemp);
    }

    测试

    #include "log.h"
    #include <iostream>
    int main()                                                                                                                                                                                                                                                                     
    {
        LOG::SetLogLevel(LogLevel::ERR);
    
        LOG::INFO("%s
    ", "久旱逢甘露");
        LOG::WARN("%s
    ", "他乡遇故知");
        LOG::ERR("%s
    ", "洞房花烛夜");
        LOG::ERR("%s
    ", "金榜题名时");
    }

    日志输出

    orejia@debian9:log$ ./demo 
    2019/11/29 15:1:49:255:949 洞房花烛夜
    2019/11/29 15:1:49:256:25 金榜题名时

    参考资料

    简洁版 https://blog.csdn.net/iw1210/article/details/53591565 

    纯C日志函数库zlog使用手册 http://hardysimpson.github.io/zlog/UsersGuide-CN.html#htoc1

    C-log https://www.cnblogs.com/prophet-ss/p/8025825.html

    日志切割 https://www.cnblogs.com/areyouready/p/9334872.html

    日志切割之logrotate https://www.cnblogs.com/clsn/p/8428257.html

  • 相关阅读:
    【C语言】创建一个函数,利用该函数将字符串中的小写字母转换为大写字母
    【C语言】输入5个整数并按输入顺序逆序输出
    【C语言】(数组)C语言字符串中的小写字母转换为大写字母
    【C语言】创建一个函数,判断某一正整数是否为完数,并调用这个函数找出1000以内所有完数
    美国正在研制一种无线电波武器,用于阻止超速行驶的汽车
    小米7的传闻:这是我们迄今为止知道的
    黑客教父郭盛华:8种方法能快速重构整体代码库
    苹果正制造一款疯狂的“16K”VR耳机,效果到底有多牛?
    日本每年培养200多名超级黑客,目的是什么?原来和中国有关
    未来实地培训会被淘汰!中国在线教育公司发起激烈的招聘热潮
  • 原文地址:https://www.cnblogs.com/orejia/p/12114806.html
Copyright © 2020-2023  润新知