C语言编写的一个简单通用的日志框架----支持日志等级,日志颜色,打印到文件等设置

日常工作中常常需要输出日志进行调试,本文提供了一个C语言编写的日志框架。可以输出日志到文件或者是终端,支持日志等级设置,不同日志等级可以设置不同的颜色,另外还可以设置进程名、模块名、函数名等的输出,能够打印毫秒级时间,能够限制文件大小,使用方便,架构小巧灵活。本架构多线程的支持有待验证,每次日志调用都会使用写入,性能有待验证,另外,写满切换文件没有实现。

SimpleLog.h

/*****************************************************************************
simple log frame for test
*****************************************************************************/

#ifndef _SIMPLE_LOG_H_
#define _SIMPLE_LOG_H_

#include <stdbool.h>


#define COLOR_CTRL_CODE "\033[0;"
#define COLOR_CTRL_CLOSE "\033[0m"

#define F_RED           "31m"
#define F_GREEN         "32m"
#define F_YELLOW        "33m"
#define F_NONE          "0m"

#define COLOR_ERROR     F_RED       // 错误
#define COLOR_WARN      F_YELLOW    // 警告
#define COLOR_INFO      F_GREEN     // 信息
#define COLOR_DEBUG     F_NONE      // 调试

// 日志级别
#define LOG_LEVEL_ERROR     0  // 错误
#define LOG_LEVEL_WARN      1  // 警告
#define LOG_LEVEL_INFO      2  // 信息
#define LOG_LEVEL_DEBUG     3  // 调试
#define LOG_LEVEL_MAX LOG_LEVEL_DEBUG

// 日志输出目标
#define LOG_TARGET_TERM 0  //输出到终端
#define LOG_TARGET_FILE 1  //输出到文件


bool SlogInit(int _iTarget, int _iLevel, const char *_strPath);
bool SlogDeinit();

bool SlogSetLevel(int _iLevel);
bool SlogGetLevel(int *_iLevel); 

void Slog(int _iLevel, const char* format, ...);


//重定位日志接口
#define LOG_MAIN "logtest" //进程名
#define LOG_SUB "test" //模块名

#define Sdebug(arg, vl...)  \
    Slog(LOG_LEVEL_DEBUG, "[%s][%s][%s]" COLOR_CTRL_CODE COLOR_DEBUG arg COLOR_CTRL_CLOSE, LOG_MAIN, LOG_SUB, __FUNCTION__, ##vl)

#define Sinfo(arg, vl...)   \
    Slog(LOG_LEVEL_INFO, "[%s][%s][%s]" COLOR_CTRL_CODE COLOR_INFO arg COLOR_CTRL_CLOSE, LOG_MAIN, LOG_SUB, __FUNCTION__, ##vl)

#define Swarn(arg, vl...)   \
    Slog(LOG_LEVEL_WARN, "[%s][%s][%s]" COLOR_CTRL_CODE COLOR_WARN arg COLOR_CTRL_CLOSE, LOG_MAIN, LOG_SUB, __FUNCTION__, ##vl)

#define Serror(arg, vl...)  \
    Slog(LOG_LEVEL_ERROR, "[%s][%s][%s]" COLOR_CTRL_CODE COLOR_ERROR arg COLOR_CTRL_CLOSE, LOG_MAIN, LOG_SUB, __FUNCTION__, ##vl)

#endif //_SIMPLE_LOG_H_

SimpleLog.c

/*****************************************************************************
simple log frame for test
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#include "SimpleLog.h"

#define LOG_DEFAULT_PATH "./test.log"
#define LOG_MAX_SZIE (10 * 1024 * 1024)  // M

char *g_strLevel[] = {
    "error", "warn ", "info ", "debug"
};

typedef struct _TSimpleLog_ {
    FILE *fp;
    int iTarget;
    int iLevel;
    int iSize;
    char strPath[256];
}TSimpleLog;

// 日志全局信息
static TSimpleLog g_tLog = {0};


bool TimeToString(const time_t _time, char *_strTime, int iLen) {
    struct tm *p = NULL;

    p = localtime(&_time);
    p->tm_year = p->tm_year + 1900;
    p->tm_mon = p->tm_mon + 1;
 
    snprintf(_strTime, iLen, "%04d-%02d-%02d %02d:%02d:%02d",
            p->tm_year, p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);

    return true;
}


bool SlogInit(int _iTarget, int _iLevel, const char *_strPath) {

    g_tLog.iTarget = _iTarget;
    g_tLog.iLevel = _iLevel;
    g_tLog.iSize = 0;

    if(g_tLog.iLevel > LOG_LEVEL_MAX) {
        g_tLog.iLevel = LOG_LEVEL_MAX;
    }
    
    if(NULL == _strPath) {
        strncpy(g_tLog.strPath, LOG_DEFAULT_PATH, sizeof(g_tLog.strPath)-1);
    } else {
        strncpy(g_tLog.strPath, _strPath, sizeof(g_tLog.strPath)-1);
    }

    printf("Log path is %s\n", g_tLog.strPath);
    g_tLog.fp = fopen(g_tLog.strPath, "w+");
    if(NULL == g_tLog.fp) {
        printf("fp is null !");
        return false;
    }

    return true;
}

bool SlogDeinit() {

    if(NULL != g_tLog.fp) {
        fflush(g_tLog.fp);
        fclose(g_tLog.fp);
    }

    return true;
}

bool SlogSetLevel(int _iLevel) {
    g_tLog.iLevel = _iLevel;
    if(g_tLog.iLevel > LOG_LEVEL_MAX) {
        g_tLog.iLevel = LOG_LEVEL_MAX;
    }
    return true;
}

bool SlogGetLevel(int *_iLevel) {
    *_iLevel = g_tLog.iLevel;
    return true;
}

void Slog(int _iLevel, const char* format, ...) {
    if(_iLevel > LOG_LEVEL_MAX) {
        _iLevel = LOG_LEVEL_MAX;
    }

    if(NULL == g_tLog.fp || _iLevel >  g_tLog.iLevel) {
        return;
    }
    va_list ap;
    char strTimeBuf[32] = {0};
    struct timeval sCurTm = {0};

    gettimeofday(&sCurTm, NULL);
    TimeToString(sCurTm.tv_sec, strTimeBuf, sizeof(strTimeBuf));

    if(LOG_TARGET_TERM == g_tLog.iTarget) {
        printf("[%s.%03d][%s]", strTimeBuf, (int)sCurTm.tv_usec/1000, g_strLevel[_iLevel]);

        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);

        return;
    }

    //大于最大重新打开
    if (g_tLog.iSize > LOG_MAX_SZIE) {
        fclose(g_tLog.fp);
        g_tLog.fp = fopen(g_tLog.strPath, "w+");
        if (NULL == g_tLog.fp) {
            printf("fp is null !");
            return;
        }
        g_tLog.iSize = 0;
    }

    g_tLog.iSize += fprintf(g_tLog.fp, "[%s.%03d][%s]", strTimeBuf, (int)sCurTm.tv_usec/1000, g_strLevel[_iLevel]);

    va_start(ap, format);
    g_tLog.iSize += vfprintf(g_tLog.fp, format, ap);
    va_end(ap);

    fflush(g_tLog.fp);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "SimpleLog.h"

int main() {

    SlogInit(LOG_TARGET_TERM, LOG_LEVEL_DEBUG, "./test.log");

    Slog(LOG_LEVEL_ERROR, "hello world!\n");
    Slog(LOG_LEVEL_WARN, "hello world!\n");
    Slog(LOG_LEVEL_INFO, "hello world!\n");
    Slog(LOG_LEVEL_DEBUG, "hello world!\n");

    Serror("hello world!\n");
    Swarn("hello world!\n");
    Sinfo("hello world!\n");
    Sdebug("hello world!\n");

    SlogDeinit();

    return 0;
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值