日志库(C语言简洁版)

版权声明:这里将不定期发布一些技术上分享,如对文章有任何意见或者建议,欢迎评论,转载请注明出处。 https://blog.csdn.net/goal_ff/article/details/90051323

说明:

  1. 使用时只需要包含log.h;
  2. 在变参列表读取解析位置有个小bug,vsnprintf()对不正确的格式匹配会出错,应该尽量在日志输出以避免;
  3. 日志输出原则:分级输出、信息列对齐、使用简单;
  4. 后续改进:添加配置读取(级别,输出位置);

功能文件 log.h 

/* 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\n", log_output);
    return nWrittenBytes;
}
 
#endif

测试文件 main.c 

/* main.c */                                                                                                               
#include "log.h"
 
int main()
{
    if(LogInit(LOG_INFOR, "forever.log"))
    {   
        printf("log init failed.\n");
        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

猜你喜欢

转载自blog.csdn.net/goal_ff/article/details/90051323