C语言实现彩色log输出,教你配置颜色分明的日志

本文介绍了如何在C语言环境中快速实现日志输出功能,包括日志级别定义、宏定义以及彩色日志的输出。通过提供的log.h和log.c文件,开发者可以在10分钟内设置并使用彩色日志系统,便于调试和查看程序运行状态。

前言

c语言实现一下日志输出容易吗?

容易。

要多久?

10分钟。

一、准备工作

终端工具:

SecureCRT 8.7

https://download.youkuaiyun.com/download/m_pfly_fish/20056079

二、安装SecureCRT

1.根据压缩包中的安装教程进行安装

2.设置crt相关配置:

        session options是指设置当前会话(当前连接的这个shell起效)的选项

        global options是指设置全局会话(对以后连接的所有shell起效)的选项

        选择 global options 进行全局设置

        关闭 scroll to bottom on output ,这样不会每次有 log 时都跳到最低端

        设置 terminal 为 linux 风格,设置 logical rows 为35(这个数据根据自己显示器分辨率来设置,我的35刚好),设置 logical columns 为128(这个数值够了),设置 Retain size and font。设置 scrollback buffer 大小为5000(这样可以缓存更多的 log )。

        设置 line wrap 和 new line mode 两项,这两项比较重要,很多 log 水平显示不完全,log 换行未从头显示的问题都是因为这两个选项导致的。

        基本配置这些够了,其他的可以根据自己的喜好设置。

三、创建串口

        完成以上配置后,创建串口

        根据相关参数配置。

四、代码编辑

1. log.h文件

        在头文件中添加以下代码

#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>

typedef enum {
    E_LOGV = 1,
    E_LOGD,
    E_LOGI,
    E_LOGW,
    E_LOGE,
} LOG_LEVEL_E;

typedef enum {
    LOG_NONE,       /*!< No log output */
    LOG_ERROR,      /*!< Critical errors, software module can not recover on its own */
    LOG_WARN,       /*!< Error conditions from which recovery measures have been taken */
    LOG_INFO,       /*!< Information messages which describe normal flow of events */
    LOG_DEBUG,      /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
    LOG_VERBOSE     /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
} log_level_t;

void log_write(log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4)));

uint32_t log_timestamp(void);

#define LOG_COLOR_BLACK   "30"
#define LOG_COLOR_RED     "31"
#define LOG_COLOR_GREEN   "32"
#define LOG_COLOR_BROWN   "33"
#define LOG_COLOR_BLUE    "34"
#define LOG_COLOR_PURPLE  "35"
#define LOG_COLOR_CYAN    "36"
#define LOG_COLOR(COLOR)  "\033[0;" COLOR "m"
#define LOG_BOLD(COLOR)   "\033[1;" COLOR "m"
#define LOG_RESET_COLOR   "\033[0m"
#define LOG_COLOR_E       LOG_COLOR(LOG_COLOR_RED)
#define LOG_COLOR_W       LOG_COLOR(LOG_COLOR_BROWN)
#define LOG_COLOR_I       LOG_COLOR(LOG_COLOR_GREEN)
#define LOG_COLOR_D
#define LOG_COLOR_V

#define LOG_FORMAT(letter, format)  LOG_COLOR_ ## letter #letter " (%d) %s: " format LOG_RESET_COLOR "\n"

#define LOG_LEVEL(level, tag, format, ...) do {                     \
        if (level==LOG_ERROR )          { log_write(LOG_ERROR,      tag, LOG_FORMAT(E, format), log_timestamp(), tag, ##__VA_ARGS__); } \
        else if (level==LOG_WARN )      { log_write(LOG_WARN,       tag, LOG_FORMAT(W, format), log_timestamp(), tag, ##__VA_ARGS__); } \
        else if (level==LOG_DEBUG )     { log_write(LOG_DEBUG,      tag, LOG_FORMAT(D, format), log_timestamp(), tag, ##__VA_ARGS__); } \
        else if (level==LOG_VERBOSE )   { log_write(LOG_VERBOSE,    tag, LOG_FORMAT(V, format), log_timestamp(), tag, ##__VA_ARGS__); } \
        else                                { log_write(LOG_INFO,       tag, LOG_FORMAT(I, format), log_timestamp(), tag, ##__VA_ARGS__); } \
    } while(0)

#define LOGE( tag, format, ... ) LOG_LEVEL(LOG_ERROR,   tag, format, ##__VA_ARGS__)
#define LOGW( tag, format, ... ) LOG_LEVEL(LOG_WARN,    tag, format, ##__VA_ARGS__)
#define LOGI( tag, format, ... ) LOG_LEVEL(LOG_INFO,    tag, format, ##__VA_ARGS__)
#define LOGD( tag, format, ... ) LOG_LEVEL(LOG_DEBUG,   tag, format, ##__VA_ARGS__)
#define LOGV( tag, format, ... ) LOG_LEVEL(LOG_VERBOSE, tag, format, ##__VA_ARGS__)

#define DEF_LOG_DEFAULT_LEVEL E_LOGV

#define LOG(level, tag, format, ...) do {                                   \
        if(level >= DEF_LOG_DEFAULT_LEVEL){                                     \
            switch(level) {                                                     \
                case E_LOGV: LOGV( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;      \
                case E_LOGD: LOGD( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;      \
                case E_LOGI: LOGI( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;      \
                case E_LOGW: LOGW( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;      \
                case E_LOGE: LOGE( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;      \
                default: LOGI( tag, "%d:%s:"format, __LINE__, __FUNCTION__, ##__VA_ARGS__);break;          \
            }                                                                   \
        }                                                                       \
    } while(0);
#define ASSERT(expr)    assert(expr)

2. log.c文件

        在 .c 文件中添加以下代码

void log_write(log_level_t level,
               const char *tag,
               const char *format, ...)
{
    va_list arg;
    va_start(arg, format);
    vprintf(format, arg);
    va_end(arg);
}

uint32_t log_timestamp()
{
    uint32_t time = OS_GetTicks();
    return time;
}

        之后就可以在应用代码中实现彩色日志输出了,例:

static const char *tag = "APP_MAIN";

LOG(E_LOGI, tag, "Hello world!");

备注:

        OS_GetTicks() 此函数为 freertos 中获取系统时间 api,打印日志时如果不需要时间戳可以修改以下代码

#define LOG_FORMAT(letter, format)  LOG_COLOR_ ## letter #letter " %s: " format LOG_RESET_COLOR "\n"

#define LOG_LEVEL(level, tag, format, ...) do {                     \
        if (level==LOG_ERROR )          { log_write(LOG_ERROR,      tag, LOG_FORMAT(E, format), tag, ##__VA_ARGS__); } \
        else if (level==LOG_WARN )      { log_write(LOG_WARN,       tag, LOG_FORMAT(W, format), tag, ##__VA_ARGS__); } \
        else if (level==LOG_DEBUG )     { log_write(LOG_DEBUG,      tag, LOG_FORMAT(D, format), tag, ##__VA_ARGS__); } \
        else if (level==LOG_VERBOSE )   { log_write(LOG_VERBOSE,    tag, LOG_FORMAT(V, format), tag, ##__VA_ARGS__); } \
        else                                { log_write(LOG_INFO,       tag, LOG_FORMAT(I, format), tag, ##__VA_ARGS__); } \
    } while(0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值