C/C++语言宏日志

136 阅读2分钟

缘由

项目调试过程中逐步完善的c/c++单文件日志输出宏

/**
 * 方便打印日志
 * 为了保证输出顺序 都使用stdout而不是stderr
 *
 * 可配置项(默认都是未定义)
 * LOG_LINE_END_CRLF        默认是\n结尾 添加此宏将以\r\n结尾
 * LOG_FOR_MCU              MCU项目可配置此宏 更适用于MCU环境
 * LOG_NDEBUG               关闭LOGD的输出
 * LOG_SHOW_VERBOSE         显示LOGV的输出
 * LOG_NOT_EXIT_ON_FATAL    FATAL默认退出程序 添加此宏将不退出
 */#pragma once#ifdef __cplusplus
#include <cstdio>
#include <cstring>
#include <cstdlib>
#else
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#endif/* 输出日志等级 */
#define LOG_LVL_FATAL                       0
#define LOG_LVL_ERROR                       1
#define LOG_LVL_WARN                        2
#define LOG_LVL_INFO                        3
#define LOG_LVL_DEBUG                       4
#define LOG_LVL_VERBOSE                     5// 配置
//#define LOG_TIMER
#define LOG_FOR_MCU
#define LOG_LINE_END_CRLF
#define LOG_WITH_RUN_TIMER
#define LOG_RUN_TIMER_WITH_MS
#define LOG_OUTPUT_LVL LOG_LVL_INFO
////////////////////////#ifdef  LOG_LINE_END_CRLF
#define LOG_LINE_END        "\r\n"
#else
#define LOG_LINE_END        "\n"
#endif#ifdef LOG_NOT_EXIT_ON_FATAL
#define LOG_EXIT_PROGRAM()
#else
#ifdef LOG_FOR_MCU
#define LOG_EXIT_PROGRAM()      do{ for(;;); } while(0)
#else
#define LOG_EXIT_PROGRAM()      exit(EXIT_FAILURE)
#endif
#endif#define LOG_BASE_FILENAME \
    (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : \
    strrchr(__FILE__, '\') ? strrchr(__FILE__, '\') + 1 : __FILE__)
​
#define LOG_WITH_COLOR
#if defined(_WIN32) || defined(LOG_FOR_MCU)
#undef LOG_WITH_COLOR
#endif
​
#ifdef LOG_WITH_RUN_TIMER
#ifdef LOG_RUN_TIMER_WITH_MS
#define LOG_RUN_TIMER_FUN System_GetTimeInterval()/1000
#define LOG_RUN_TIMER_FMT "-T(%lums)"
#else
#define LOG_RUN_TIMER_FUN System_GetTimeInterval()
#define LOG_RUN_TIMER_FMT "-T(%luus)"
#endif
#else
#define LOG_RUN_TIMER_FUN
#define LOG_RUN_TIMER_FMT
#endif
​
#ifdef LOG_WITH_COLOR
#define LOG_COLOR_RED       "\033[31m"
#define LOG_COLOR_GREEN     "\033[32m"
#define LOG_COLOR_YELLOW    "\033[33m"
#define LOG_COLOR_BLUE      "\033[34m"
#define LOG_COLOR_CARMINE   "\033[35m"
#define LOG_COLOR_CYAN      "\033[36m"
#define LOG_COLOR_DEFAULT
#define LOG_COLOR_END       "\033[m"
#else
#define LOG_COLOR_RED
#define LOG_COLOR_GREEN
#define LOG_COLOR_YELLOW
#define LOG_COLOR_BLUE
#define LOG_COLOR_CARMINE
#define LOG_COLOR_CYAN
#define LOG_COLOR_DEFAULT
#define LOG_COLOR_END
#endif
​
#define LOG_END                 LOG_COLOR_END LOG_LINE_END
​
// 带时钟输出
#if defined(LOG_TIMER)
#define LOGT(tag, fmt, ...)     do{ printf(LOG_COLOR_BLUE "[" tag "]" LOG_RUN_TIMER_FMT ": " fmt LOG_END,LOG_RUN_TIMER_FUN, ##__VA_ARGS__); } while(0)
#else
#define LOGT(fmt, ...)          ((void)0)
#endif
​
// 等级输出
#if LOG_OUTPUT_LVL >= LOG_LVL_FATAL
#define LOGF(fmt, ...)          do{ printf(LOG_COLOR_CYAN "[F]: %s: %s: %d: " fmt LOG_END, LOG_BASE_FILENAME, __func__, __LINE__, ##__VA_ARGS__); LOG_EXIT_PROGRAM(); } while(0)
#else
#define LOGF(fmt, ...)          ((void)0)
#endif
​
#if LOG_OUTPUT_LVL >= LOG_LVL_ERROR
#define LOGE(fmt, ...)          do{ printf(LOG_COLOR_RED "[E]: %s: %s: %d: " fmt LOG_END, LOG_BASE_FILENAME, __func__, __LINE__, ##__VA_ARGS__); } while(0)
#else
#define LOGE(fmt, ...)          ((void)0)
#endif
​
#if LOG_OUTPUT_LVL >= LOG_LVL_WARN
#define LOGW(fmt, ...)          do{ printf(LOG_COLOR_CARMINE "[W]: %s: %s: %d: " fmt LOG_END, LOG_BASE_FILENAME, __func__, __LINE__, ##__VA_ARGS__); } while(0)
#else
#define LOGW(fmt, ...)          ((void)0)
#endif
​
#if LOG_OUTPUT_LVL >= LOG_LVL_INFO
#define LOGI(fmt, ...)          do{ printf(LOG_COLOR_YELLOW "[I]: %s: " fmt LOG_END, LOG_BASE_FILENAME, ##__VA_ARGS__); } while(0)
#else
#define LOGI(fmt, ...)          ((void)0)
#endif
​
#if LOG_OUTPUT_LVL >= LOG_LVL_DEBUG
#define LOGD(fmt, ...)          do{ printf(LOG_COLOR_DEFAULT "[D]: %s: " fmt LOG_END, LOG_BASE_FILENAME, ##__VA_ARGS__); } while(0)
#else
#define LOGD(fmt, ...)          ((void)0)
#endif
​
#if LOG_OUTPUT_LVL >= LOG_LVL_VERBOSE
#define LOGV(fmt, ...)          do{ printf(LOG_COLOR_DEFAULT "[V]: %s: " fmt LOG_END, LOG_BASE_FILENAME, ##__VA_ARGS__); } while(0)
#else
#define LOGV(fmt, ...)          ((void)0)
#endif
​

本文使用 文章同步助手 同步