打印
[资源分享]

调试神器--Rlog

[复制链接]
1788|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
coshi|  楼主 | 2023-11-13 09:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
概述
在现代软件开发中,日志记录系统是不可或缺的一部分。它不仅可以帮助开发人员在应用程序中定位和解决问题,还可以用于监控、性能分析、安全审计等方面。本文将介绍日志记录系统的基本概念、重要性以及如何构建一个高效的日志记录系统。

为什么需要日志记录系统?
日志是应用程序在运行时生成的文本消息,用于记录关键事件、错误信息、警告以及其他有价值的信息。日志记录系统的作用如下:

故障排除与问题定位:当应用程序出现问题时,日志可以提供关于发生了什么、在哪里发生以及为什么发生的关键信息,帮助开发人员快速定位和解决问题。
性能分析:通过记录关键操作的时间戳和执行时间,开发人员可以分析应用程序的性能瓶颈,并进行优化。
监控与报警:监控系统可以分析日志,实时监控应用程序的健康状态。当出现异常情况时,可以触发报警机制,使团队可以及时采取措施。
安全审计:记录安全相关事件和访问,以便进行后续的审计和分析。
构建日志记录系统的关键步骤
日志级别与分类:日志级别包括调试(Debug)、信息(Info)、警告(Warning)、错误(Error)等。不同级别的日志用于不同目的,例如调试时使用调试日志来追踪代码执行,而错误日志用于记录严重的问题。选择合适的日志级别可以避免日志信息过于冗杂或过于稀少。
日志格式与结构:一个良好的日志格式应包括时间戳、日志级别、模块/组件名以及具体的日志消息。统一的格式使得日志易于阅读和分析。例如:[时间戳] [日志级别] [模块名] - 日志消息
异步日志写入:为避免阻塞应用程序的正常执行,可以采用异步日志写入方式。日志消息被缓冲并在适当的时机写入磁盘,从而提高应用程序的性能。
日志存储与滚动: 考虑使用滚动策略,定期归档或删除旧的日志文件,以免日志文件无限增大。选择适当的存储方式,如本地文件、数据库或云存储。
上下文信息:除了基本的日志信息外,还可以在日志中添加上下文信息,如用户ID、请求ID、会话ID等。这些信息有助于在复杂的分布式系统中跟踪请求流程。
敏感信息与安全:避免将敏感信息(如密码、API密钥)写入日志。同时,实施权限控制,限制对日志文件的访问,确保敏感信息不被滥用。
日志分析与可视化:利用日志分析工具或平台,对日志进行聚合、搜索和可视化分析。这有助于发现模式、趋势以及潜在问题。
Rlog组件
Rlog作为一款高性能的纯C语言日志组件,为开发人员提供了一种轻松、灵活且可定制的日志记录解决方案。其简单的接口和插件扩展功能使得它适用于各种不同规模和类型的项目。无论是小型应用程序还是大型系统,Rlog都能为您提供高效的日志记录支持,帮助您更好地理解和管理应用程序的运行状态。

纯C语言开发:Rlog完全由C语言编写,因此具有广泛的可移植性和兼容性。它可以轻松地集成到各种C语言项目中。
简单的接口:Rlog提供了简单、直观的接口,使开发人员可以轻松地在代码中插入日志记录语句。这使得调试和问题定位变得更加容易。
灵活可配置:Rlog允许开发人员根据项目需求进行高度自定义的配置。您可以定义日志级别、格式、输出位置等,以满足不同应用场景的需求。
插件扩展:一个突出的特点是Rlog的插件式扩展输出端点的能力。这意味着您可以将日志消息输出到各种不同的地方,如文件、终端、远程服务器等,以适应多样化的需求。
Rlog特性
支持用户自定义输出端点(例如:串口终端、网络中断、Flash…),输出端点以插件形式自定义扩展。
日志内容可包含日志等级、时间戳、行号,函数信息,文件信息;
支持多种操作系统(RT-Thread、Linux…),也支持裸机平台;
日志输出支持:printf原始格式,日志等级输出,hexdump输出;
Rlog目录结构
.
├── example
│   ├── rlog_linux_adapter.c        /* linux环境下的适配接口 */
│   └── rlog_rtt_adapter.c          /* rt-thread环境下的适配接口 */
├── include/
│   ├── rlog_adapter.h              /* rlog适配描述 */
│   └── rlog.h                      /* rlog对外接口 */
├── main.c                          /* rlog的测试样例 */
├── Makefile                        /* linux环境rlog构建Makefile */
├── plug-in                         /* 输出端点插件的存放路径 */
├── SConscript                      /* rt-thread环境rlog构建脚本 */
└── src
    ├── rlog.c                      /* rlog核心代码 */
    ├── rlog_def.h                  /* rlog核心代码使用的定义 */
    └── rlog_utils.c                /* rlog使用的C库接口 */


Rlog灵活配置
静态配置:
静态配置采用宏定义的方式,用户可直接修改rlog_adapter.h头文件的宏定义,就可以修正相关配置;
静态配置的管控权限比动态配置的高,例如:静态配置设置日志输出总开关为关闭,动态配置设置日志输出使能,日志已经无法输出。
配置描述如下:

/* Enable log output */
#define RLOG_OUTPUT_ENABLE              1
/* Set log output level, rang: from RLOG_LEVEL_ASSERT to RLOG_LEVEL_VERBOSE */
#define RLOG_OUTPUT_LEVEL               RLOG_LEVEL_VERBOSE
/* Enable log color */
#define RLOG_COLOUR_ENABLE              1
/* Enable log color */
#define RLOG_TIME_ENABLE                1
/* Support log include directory */
#define RLOG_DIRECTORY_ENABLE           1
/* Support log include funtiong name */
#define RLOG_FUNCTION_ENABLE            1
/* Support log include line number*/
#define RLOG_LINE_ENABLE                1
/* Buffer size for every line's log */
#define RLOG_LINE_BUFF_LEN              128
/* Output line number max length */
#define RLOG_LINE_NUM_SIZE              5
/* Output newline sign */
#define RLOG_NEWLINE_SIGN               "\r\n"
/* Enable assert check */
#define RLOG_ASSERT_ENABLE              1
/* Log function. default FDB_PRINT macro is printf() */
#define RLOG_PRINT(...)                 printf(__VA_ARGS__)



动态配置:
动态配置采用接口的方式,用户通过调用rlog.h头文件提供的接口设置;
动态配置的管控权限比静态配置的低,例如:静态配置设置日志输出总开关为关闭,动态配置设置日志输出使能,日志已经无法输出。
/**
* RLog output enable
*
* @param enable true: enable output, false: disable output
*/
void rlog_enable(bool enable);
/**
* RLog output color enable
*
* @param enable true: enable output color, false: disable output color
*/
void rlog_color_enable(bool enable);
/**
* RLog level output format setting
*
* @param level  log level
* @param format log format
*/
void rlog_level_fmt_set(rlog_lvl_t level, int format);
/**
* RLog level output format setting
*
* @param level  log level
* @param format log format
*
* @return result true: supported format, false: unsupported format
*/
bool rlog_level_fmt_get(rlog_lvl_t level, int format);
/**
* RLog filter the content of the log level
*
* @param level  log level
*/
void rlog_level_filter_set(rlog_lvl_t level);



Rlog适配
不同平台的适配方式不同,所以为rlog核心层提供了统一的接口,适配接口如下:
void rlog_adapter_init(void);
void rlog_adapter_deinit(void);
void rlog_lock(void);
void rlog_unlock(void);
char *rlog_get_time(void);
void rlog_output(const char *log, uint16_t len);

linux下的适配方式:
static pthread_mutex_t mutex;

void rlog_lock(void)
{
    pthread_mutex_lock(&mutex);
}

void rlog_unlock(void)
{
    pthread_mutex_unlock(&mutex);
}

char *rlog_get_time(void)
{
#define TIME_STR_SIZE       32
    static char time_str[TIME_STR_SIZE] = {0};
    time_t tmp;
    struct tm *timp;

    time(&tmp);   
    timp = localtime(&tmp);

    memset(time_str, 0, TIME_STR_SIZE);
    rlog_snprintf(time_str, TIME_STR_SIZE, "%04d-%02d-%02d %02d:%02d:%02d",
                                (1900 + timp->tm_year), (1 + timp->tm_mon), timp->tm_mday,
                                timp->tm_hour, timp->tm_min, timp->tm_sec);

    return time_str;
}

void rlog_output(const char *log, uint16_t len)
{
    RLOG_PRINT("%.*s", len, log);
}

void rlog_adapter_init(void)
{
    pthread_mutex_init(&mutex, NULL);
}

void rlog_adapter_deinit(void)
{
    pthread_mutex_destroy(&mutex);
}



Rlog验证
rlog验证以linux环境为例,Rlog开源路径:https://gitee.com/RiceChen0/rlog
rlog验证操作流程:
youyeetoo@youyeetoo:~$ git clone https://gitee.com/RiceChen0/rlog.git
youyeetoo@youyeetoo:~/rlog$ make
youyeetoo@youyeetoo:~/rlog$ ./output/rlog_1.0.0
RLog Version: v1.0.0
RLog Author: RiceChen
RLog Contact: https://gitee.com/RiceChen0/rlog
Youyeetoo
(2023-08-15 18:53:27)[main.c main:12]I/RLOG: Youyeetoo
RLOG HexDump--Title: RLOG, len: 9
00000000: 59 6F 75 79 65 65 74 6F 6F                       Youyeetoo


rlog验证效果:


Rlog总结
rlog提供了简单易用的日志系统,采用插件方式,提供灵活的输出端点的设置。
rlog的原型参考了开源项目:https://gitee.com/RT-Thread-Mirror/EasyLogger。
rlog不依赖C库,rlog_utils.c中,重新定义了用到C库接口。接口参考了开源项目:https://gitee.com/RT-Thread-Mirror/rt_vsnprintf_full。
————————————————
版权声明:本文为CSDN博主「Rice嵌入式开发」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/baidu_29900103/article/details/133852735

使用特权

评论回复

相关帖子

沙发
chenqianqian| | 2023-11-22 08:33 | 只看该作者
这个貌似不错,回头研究一下,感谢分享。

使用特权

评论回复
板凳
tpgf| | 2023-12-2 15:29 | 只看该作者
日志记录系统都可以将那些内容记录下来呢

使用特权

评论回复
地板
gwsan| | 2023-12-2 16:31 | 只看该作者
如何把这个工具嵌入进单片机的程序里边呢

使用特权

评论回复
5
zljiu| | 2023-12-3 08:41 | 只看该作者
可以人为设定需要记录的位置或者时间点吗

使用特权

评论回复
6
tfqi| | 2023-12-3 09:27 | 只看该作者
这个插件如何移植进入程序里边呢

使用特权

评论回复
7
nawu| | 2023-12-3 10:00 | 只看该作者
这个办法好  可以在关键位置进行信息排查

使用特权

评论回复
8
aoyi| | 2023-12-3 10:41 | 只看该作者
这种组件是开源的吗?可以免费使用吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

95

主题

3301

帖子

4

粉丝