DEBUG系统

DEBUG系统

  • level 级别控制
  • 输出target 控制
  • 在终端中更改level 和target:使用环境变量实现
  • log 不同级别使用不同颜色
/*dlog.h*/
#ifndef _DLOG_H_
#define _DLOG_H_


int set_log_level(char *log_level_str, int enalbe);
int set_log_target(char *log_target, int enable, char *filename);
int dlog_debug(char *file, int line, const char *func, char *format, ...);
int dlog_info(char *file, int line, const char *func, char *format, ...);
int dlog_notice(char* file, int line, const char *func, char *format, ...);
int dlog_warn(char *file, int line, const char *func, char *format, ...);
int dlog_error(char *file, int line, const char *func, char *format, ...);
int dlog_crit(char *file, int line, const char *func, char *format, ...);
int dlog_printf(char *file, int line, const char *func, char *format, ...);
int dlog_printf_exit(char *file, int line, const char *func, char *format, ...);


#define PRINTF_EXIT(a, ...)     dlog_printf_exit(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define PRINTF(a, ...)          dlog_printf(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define DEBUG(a, ...)           dlog_debug(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define INFO(a, ...)            dlog_info(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define NOTICE(a, ...)          dlog_notice(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define WARN(a, ...)            dlog_warn(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define ERROR(a, ...)           dlog_error(__FILE__, __LINE__, __func__, a, ##__VA_ARGS__)
#define CRIT(a, ...)            dlog_crit(__FILE__, __LINE__,  __func__, a, ##__VA_ARGS__)



#endif
/*dlog.c*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <time.h>


#define DLOG_LOG_LEVEL_ENV              "DLOG_LOG_LEVEL"
#define DLOG_LOG_TARGET_ENV             "DLOG_LOG_TARGET"
#define DLOG_LOG_TARGET_FILE_ENV        "DLOG_LOG_TARGET_FILE"
#define DLOG_LOG_DEFAULT_FILE           "/tmp/dlog"

#define ARRARY_SIZE(a)  (sizeof(a)/sizeof(a[0]))
#define MESSAGE_SIZE    (4096)

enum {
    DLOG_NONE = 0,
    DLOG_CRIT,
    DLOG_ERR,
    DLOG_WARN,
    DLOG_NOTICE,
    DLOG_INFO,
    DLOG_DEBUG,
    DLOG_PRINTF,
    DLOG_TARGET_SYSLOG,
    DLOG_TARGET_STDERR,
    DLOG_TARGET_FILE,
};

struct dlog_context
{
    int log_level;
    int log_target;
    char *file_name;
    FILE *file_out;
    char message_buf[MESSAGE_SIZE];
};

struct level2str
{
    int level;
    char *level_str;
};

int level_to_syspt[] = {
    [DLOG_CRIT] = LOG_CRIT,
    [DLOG_ERR] = LOG_ERR,
    [DLOG_WARN] = LOG_WARNING,
    [DLOG_NOTICE] = LOG_NOTICE,
    [DLOG_INFO] = LOG_INFO,
    [DLOG_DEBUG] = LOG_DEBUG,
};

struct level2str key_to_str[] = {
    {DLOG_NONE,     "none"},
    {DLOG_CRIT,     "crit"},
    {DLOG_ERR,      "err"},
    {DLOG_WARN,     "warn"},
    {DLOG_NOTICE,   "notice"},
    {DLOG_INFO,     "info"},
    {DLOG_DEBUG,    "debug"},
    {DLOG_PRINTF,   "printf"},
    {DLOG_TARGET_SYSLOG,    "syslog"},
    {DLOG_TARGET_STDERR,    "stderr"},
    {DLOG_TARGET_FILE,      "file"},
};

struct dlog_context logContext = {
    .log_level = DLOG_ERR,
    .log_target = DLOG_TARGET_STDERR,
    .file_name = NULL,
    .file_out = NULL,
};

int set_log_level(char *log_level_str, int enable)
{
    return (0 == setenv(DLOG_LOG_LEVEL_ENV, log_level_str, enable));
}

int set_log_target(char *log_target, int enable, char *filename)
{
    int ret = 0;

    ret = setenv(DLOG_LOG_TARGET_ENV, log_target, enable);
    if (ret < 0)
        return -1;

    if (!strcmp(log_target, "file"))
        ret = setenv(DLOG_LOG_TARGET_FILE_ENV, filename, enable);
    
    return ret;
}

static int get_log_level(void)
{
    int ret = DLOG_ERR;
    char *log_level = secure_getenv(DLOG_LOG_LEVEL_ENV);
    if (!log_level)
        return ret;

    for (int i = 0; i < ARRARY_SIZE(key_to_str); i ++) {
        if (!strcmp(log_level, key_to_str[i].level_str)) {
            ret = key_to_str[i].level;
            break;
        }       
    }
    return ret;
}

static inline void close_file(void)
{
     fclose(logContext.file_out);
     logContext.file_name = NULL;
}

static void get_log_target(void)
{
    char *target_file = NULL;
    char *log_target = secure_getenv(DLOG_LOG_TARGET_ENV);
    int log_target_prev = logContext.log_target;
    if (!log_target)
        return;

    if (!strcmp(log_target, "syslog")) {
        if (log_target_prev != DLOG_TARGET_SYSLOG) {
            if (log_target_prev == DLOG_TARGET_FILE) {
               close_file();
            }
            logContext.log_target = DLOG_TARGET_SYSLOG;
        }
    } else if (!strcmp(log_target, "stderr")) {
        if (log_target_prev != DLOG_TARGET_STDERR) {
            if (log_target_prev == DLOG_TARGET_FILE) {
               close_file();
            }
            logContext.log_target = DLOG_TARGET_STDERR;
            logContext.file_name = NULL;
            logContext.file_out = stderr;
        }
    } else if (!strcmp(log_target, "file")) {
        logContext.log_target = DLOG_TARGET_FILE;
        target_file = secure_getenv(DLOG_LOG_TARGET_FILE_ENV);
        if (!target_file) {
            target_file = DLOG_LOG_DEFAULT_FILE;
        }
        if (log_target_prev == DLOG_TARGET_FILE) {
            if (strcmp(target_file, logContext.file_name)) {
                close_file();
                logContext.file_name = target_file;
                logContext.file_out = fopen(target_file, "a");
                if (!logContext.file_out) {
                    logContext.log_target = DLOG_TARGET_STDERR;
                    logContext.file_name = NULL;
                    logContext.file_out = stderr;
                }
            } 
        } else {
            logContext.file_name = target_file;
            logContext.file_out = fopen(target_file, "a");
            if (!logContext.file_out) {
                logContext.log_target = DLOG_TARGET_STDERR;
                logContext.file_name = NULL;
                logContext.file_out = stderr;
            }
        }
        
    }
}

static void update_context(void)
{
    if (logContext.log_target == DLOG_TARGET_STDERR)
        logContext.file_out = stderr;
   logContext.log_level = get_log_level();
   get_log_target();
   memset(logContext.message_buf, 0, MESSAGE_SIZE);
}

static void gen_prefix(int level, int target, char *file, int line, char *func, char *format)
{
    char line_no[256] = {0};
    time_t time_now;
    char *timestr = ctime(&time_now);

     strcat(logContext.message_buf, timestr);
     logContext.message_buf[strlen(timestr) - 1] ='\0';
      strcat(logContext.message_buf, ":");
    if (target == DLOG_TARGET_SYSLOG || target == DLOG_TARGET_FILE) {
        switch(level) {
            case DLOG_CRIT:
                strcat(logContext.message_buf, "[CRIT]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_ERR:
                strcat(logContext.message_buf, "[ERR]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_WARN:
                strcat(logContext.message_buf, "[WARN]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_NOTICE:
                strcat(logContext.message_buf, "[NOTICE]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_INFO:
                strcat(logContext.message_buf, "[INFO]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_DEBUG:
                strcat(logContext.message_buf, "[DEBUG]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            case DLOG_PRINTF:
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            default:;
        }
    } else {
        switch(level) {
            case DLOG_CRIT:
                //red
                strcat(logContext.message_buf, "\033[31m");
                strcat(logContext.message_buf, "[CRIT]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_ERR:
                strcat(logContext.message_buf, "\033[31m");
                strcat(logContext.message_buf, "[ERR]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_WARN:
                //yellow
                strcat(logContext.message_buf, "\033[33m");
                strcat(logContext.message_buf, "[WARN]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_NOTICE:
                //blue
                strcat(logContext.message_buf, "\033[34m");
                strcat(logContext.message_buf, "[NOTICE]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_INFO:
                //green
                strcat(logContext.message_buf, "\033[32m");
                strcat(logContext.message_buf, "[INFO]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_DEBUG:
                //light blue
                strcat(logContext.message_buf, "\033[36m");
                strcat(logContext.message_buf, "[DEBUG]:");
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                strcat(logContext.message_buf, "\033[0m");
                break;
            case DLOG_PRINTF:
                strcat(logContext.message_buf, file);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, func);
                strcat(logContext.message_buf, ":");
                 sprintf(line_no, "%d", line);
                strcat(logContext.message_buf, line_no);
                strcat(logContext.message_buf, ":");
                strcat(logContext.message_buf, format);
                break;
            default:;
        }
    }
    return;
}

int dlog_debug(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_DEBUG <= logContext.log_level) {
        gen_prefix(DLOG_DEBUG, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_DEBUG], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_info(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_INFO <= logContext.log_level) {
        gen_prefix(DLOG_INFO, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_INFO], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_notice(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_NOTICE <= logContext.log_level) {
        gen_prefix(DLOG_NOTICE, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_NOTICE], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_warn(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_WARN <= logContext.log_level) {
        gen_prefix(DLOG_WARN, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_WARN], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_error(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_ERR <= logContext.log_level) {
        gen_prefix(DLOG_ERR, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_ERR], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_crit(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    if (DLOG_CRIT <= logContext.log_level) {
        gen_prefix(DLOG_CRIT, logContext.log_target, file, line, func, format);
        switch(logContext.log_target) {
            case DLOG_TARGET_SYSLOG:
                    vsyslog(level_to_syspt[DLOG_CRIT], logContext.message_buf, vlist);
                 break;
            case DLOG_TARGET_STDERR:
            case DLOG_TARGET_FILE:
                    vfprintf(logContext.file_out, logContext.message_buf, vlist);
                    fflush(logContext.file_out);
                break;
            default:;
        }
    }

    va_end(vlist);
    return 0;
}

int dlog_printf(char *file, int line, char *func, char *format, ...)
{
    va_list vlist;

    va_start(vlist, format);
    update_context();
    gen_prefix(DLOG_PRINTF, logContext.log_target, file, line, func, format);
    switch(logContext.log_target) {
        case DLOG_TARGET_SYSLOG:
                vsyslog(level_to_syspt[DLOG_DEBUG], logContext.message_buf, vlist);
            break;
        case DLOG_TARGET_STDERR:
        case DLOG_TARGET_FILE:
                vfprintf(logContext.file_out, logContext.message_buf, vlist);
                fflush(logContext.file_out);
            break;
        default:;
    }

    va_end(vlist);
    return 0;
}

int dlog_printf_exit(char *file, int line, char *func, char *format, ...)
{
     va_list vlist;

    va_start(vlist, format);
    update_context();
    gen_prefix(DLOG_PRINTF, logContext.log_target, file, line, func, format);
    switch(logContext.log_target) {
        case DLOG_TARGET_SYSLOG:
                vsyslog(level_to_syspt[DLOG_DEBUG], logContext.message_buf, vlist);
            break;
        case DLOG_TARGET_STDERR:
        case DLOG_TARGET_FILE:
                vfprintf(logContext.file_out, logContext.message_buf, vlist);
                fflush(logContext.file_out);
            break;
        default:;
    }

    va_end(vlist);

    exit(0);
    return 0;
}
/*test_dlog.c*/
#include "dlog.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 100, b = 1000;
    
    PRINTF("value a is %d, b is %d\n", a, b);
    DEBUG("value a is %d, b is %d\n", a, b);
    INFO("value a is %d, b is %d\n", a, b);
    NOTICE("value a is %d, b is %d\n", a, b);
    WARN("value a is %d, b is %d\n", a, b);
    ERROR("value a is %d, b is %d\n", a, b);
    CRIT("value a is %d, b is %d\n", a, b);
}
/*makefile*/

.phony: all clean

SRCS:= test_dlog.c dlog.c
TARGET:= test_dlog

all: $(TARGET)

$(TARGET): $(SRCS)
	gcc -o $@ $^

clean:
	rm -f $(TARGET)

 # export DLOG_LOG_TARGET=stderr
 # export DLOG_LOG_LEVEL=none
 # ./test_dlog 
Thu Jan  1 08:00:00 1970:test_dlog.c:main:8:value a is 100, b is 1000
 # export DLOG_LOG_TARGET=stderr
 # export DLOG_LOG_LEVEL=debug

在这里插入图片描述

头文件中简单的DEBUG

#ifndef __DECOD_DEBUG_H__
#define __DECOD_DEBUG_H__

#include <stdio.h>

enum {
    E_INFO = 0,
    E_NOTICE,
    E_DEBUG,
    E_WARRN,
    E_ERROR,
};

#define LOG_LEVEL 0

#ifdef LOG_LEVEL 
#define LOG_OUT(level, color, tag, str, ...)  (\
                            (tag >= LOG_LEVEL)? \
                             fprintf(stdout, color tag "%s:%d:"\
                                    str "\e[0m", __FILE__, __LINE__, \
                                    ##__VA_ARGS__):0); 
#else
#define LOG_OUT(tag, color, str, ...)  
#endif

#define INFO(a, ...) LOG_OUT(E_INOF, "\e[1;32m", "[INFO]", a, ##__VA_ARGS__)
//yellow
#define NOTICE(a, ...) LOG_OUT(E_NOTICE, "\e[1;43m", "[NOTICE]:", a, ##__VA_ARGS__)
//green 
#define DEBUG(a, ...) LOG_OUT(E_DEBUG, "\e[1;42m", "[DEBUG]:", a, ##__VA_ARGS__)
//blue
#define WARRN(a, ...) LOG_OUT(E_WARRN, "\e[1;34m", "[WARRN]:", a, ##__VA_ARGS__)
//red
#define ERROR(a, ...) LOG_OUT(E_ERROR, "\e[1;41m", "[ERROR]:", a, ##__VA_ARGS__)

#define INFO_EXIT(...)  do {INFO(__VA_ARGS__); exit(0); } while(0)
#endif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值