这两天发现一个还不错的开源项目,记录一下学习心得。对于嵌入式底层应用开发,基本离不开日志功能,这种轮子有很多,log.c 最简单,达到了开箱即用的级别。
点击查看大图log.c 的几个特点:代码简洁,就一个 .c 和 .h 文件,一共 200 行。设计优雅,打印日志的 API 只有 1 个。提供了将 log 输入到不同目标的接口,例如输入到文件。提供了实现线程安全的接口。
点击查看大图全局变量 L 维护了 log.c 所需要的所有信息。void *udata 用于保存用户数据,用户可以将其用作任意用途。lock 是一个函数指针:。
点击查看大图一条 log 信息对应一个 log_Event。暴露这个数据结构是为了用户可以编写自己的 log 打印函数 log_LogFn 以输出 log。公共的 API:整个 log.c 其实只提供了一个打印相关的 API:log_log()。log_trace() 等宏只是对 log_log() 的简单封装,这种简洁地设计无论是对库的用户还是对库的开发者而言,都是最幸福的事情。剩下的几个 API 用于控制和功能扩展。log_log() 的实现思路:1> 根据用于提供的 log 信息构造 1个 log_Event。2> 将 log 信息输出到标准输出。3> 遍历所有 log Callback,逐一调用它们的打印函数 log_LogFn。
log.c 是什么?
https://github.com/rxi/log.c 简单地说,log.c 就是一个 C 语言的日志功能模块。
点击查看大图log.c 的几个特点:代码简洁,就一个 .c 和 .h 文件,一共 200 行。设计优雅,打印日志的 API 只有 1 个。提供了将 log 输入到不同目标的接口,例如输入到文件。提供了实现线程安全的接口。 log.c 怎么用?
打印日志的 API:log_trace(constchar*fmt,...); log_debug(constchar*fmt,...); log_info(constchar*fmt,...); log_warn(constchar*fmt,...); log_error(constchar*fmt,...); log_fatal(constchar*fmt,...); 它们都是对 log_log() 的简单封装,用法和 printf() 一样。示例:下面的例子会将日志同时输出到标准输出和文件中。
#include"log.h" intmain(intargc,char*argv[]) { log_set_level(0); log_set_quiet(0); FILE*fp1,*fp2; fp1=fopen("./log_info.txt","ab"); if(fp1==NULL) return-1; fp2=fopen("./log_debug.txt","ab"); if(fp2==NULL) return-1; log_add_fp(fp1,LOG_INFO); log_add_fp(fp2,LOG_DEBUG); log_debug("debug"); log_info("info"); log_warn("warn"); fclose(fp2); fclose(fp1); return0; } 运行:
$./example1 2305DEBUGexample1.cdebug 2305INFOexample1.cinfo 2305WARNexample1.cwarn $catlog_debug.txt 2022-05-082305DEBUGexample1.cdebug 2022-05-082305INFOexample1.cinfo 2022-05-082305WARNexample1.cwarn $catlog_info.txt 2022-05-082305INFOexample1.cinfo 2022-05-082305WARNexample1.cwarn 关于线程安全:log.c 代码虽然少,但是仍然考虑了线程安全,下面是用法示例。
#include"log.h" pthread_mutex_tMUTEX_LOG; voidlog_lock(boollock,void*udata); intmain() { log_set_level(0); log_set_quiet(0); pthread_mutex_init(&MUTEX_LOG,NULL); log_set_lock(log_lock,&MUTEX_LOG); /*Insertthreadedapplicationcodehere...*/ log_info("I'mthreadsafe"); pthread_mutex_destroy(&MUTEX_LOG); return0; } voidlog_lock(boollock,void*udata) { pthread_mutex_t*LOCK=(pthread_mutex_t*)(udata); if(lock) pthread_mutex_lock(LOCK); else pthread_mutex_unlock(LOCK); }
log.c 的内部实现?
私有数据结构:
点击查看大图全局变量 L 维护了 log.c 所需要的所有信息。void *udata 用于保存用户数据,用户可以将其用作任意用途。lock 是一个函数指针:。typedefvoid(*log_LockFn)(boollock,void*udata); 用户可以用它来指定自己想用的锁机制,例如 Pthread 的互斥量。int level 用于保存当前的 log 等级,等级大于 level 的 log 才会被输出到标准输出。bool quiet 用于打开、关闭 log 输出。数组 callbacks 用于保存多种输出方式,目前仅支持输出到标准输出和文件,有需要的话我们还可以将其扩展成输出到 syslog、网络等,每增加一种输出方式就是构造一个 Callback,成员回调函数 log_LogFn 负责真正地 log 输出功能:
typedefvoid(*log_LogFn)(log_Event*ev); 公共数据结构:
点击查看大图一条 log 信息对应一个 log_Event。暴露这个数据结构是为了用户可以编写自己的 log 打印函数 log_LogFn 以输出 log。公共的 API:整个 log.c 其实只提供了一个打印相关的 API:log_log()。log_trace() 等宏只是对 log_log() 的简单封装,这种简洁地设计无论是对库的用户还是对库的开发者而言,都是最幸福的事情。剩下的几个 API 用于控制和功能扩展。log_log() 的实现思路:1> 根据用于提供的 log 信息构造 1个 log_Event。2> 将 log 信息输出到标准输出。3> 遍历所有 log Callback,逐一调用它们的打印函数 log_LogFn。 总结
log.c 代码优雅、设计简洁、功能实用,这对库的用户和库的开发者而言,都是一种幸福。如果你的项目需要一个简单好用的日志功能,可以考虑集成开箱即用的 log.c审核编辑 :李倩
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
嵌入式
+关注
关注
5186文章
20155浏览量
328966 -
开源项目
+关注
关注
0文章
38浏览量
7564
原文标题:调试利器!一款轻量级日志库 log.c
文章出处:【微信号:knifewheat,微信公众号:小麦大叔】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
热点推荐
【瑞萨RA6E2】板载uart测试,控制台shell及带颜色输出log的实现
的调试信息类型显示不同的颜色,接下来也实现一下。
这里直接贴.c.h出代码,如下:
log.c
/**
* @file log.c
* @author Letter
发表于 11-09 23:50
easyflash 写入多条log保存到flash成功,读取多条失败是怎么回事?
很多人都在推,所以我就用了。
按照教程,我只需要log保存功能,使能EF_USING_LOG,ENV跟IAP暂时不需要,所以全部屏蔽了。
#ifndef EF_CFG_H_
#define
发表于 09-24 07:13
Texas Instruments LOG300DEVM和LOG300RGTEVM评估模块数据手册
Texas Instruments LOG300DEVM和LOG300RGTEVM评估模块 (EVM) 设计用于评估集成对数检波器、低噪声放大器 (LNA) 和输入频率检测器的性能,所有这些都集成在
Texas Instruments LOG200EVM放大器评估模块 (EVM)数据手册
Texas Instruments LOG200EVM放大器评估模块 (EVM) 是一个用于评估LOG200的开发平台,LOG200是一款精密、高速对数放大器,集成了光电二极管偏置和暗电流校正功能
Texas Instruments LOG300 40MHz对数探测器数据手册
Texas Instruments LOG300 40MHz对数探测器是一款由低噪声放大器 (LNA) 和对数探测器模块组成的集成模拟前端 (AFE)。该器件支持高达40MHz的输入频率范围
Texas Instruments LOG200精密高速对数放大器数据手册
Texas Instruments LOG200精密高速对数放大器是一款宽动态范围电流到电压放大器,设计旨在优化160dB动态范围内的电流测量。该器件具有无与伦比的精度和速度,用在医疗诊断、光通信
CYW20829全双工UART和I2C Master同时工作导致UART log输出异常怎么解决?
CYW20829使用code example HAL_I2C_Master, 修改UART使用P1_3, P1_2, 修改I2C Master使用P0_3, P0_2, uart log和I2
发表于 06-27 07:57
easyflash 写入多条log保存到flash成功,读取多条失败的原因?
很多人都在推,所以我就用了。
按照教程,我只需要log保存功能,使能EF_USING_LOG,ENV跟IAP暂时不需要,所以全部屏蔽了。
#ifndef EF_CFG_H_
#define
发表于 06-13 07:02
全栈开发进阶指南:LuatOS-log库从入门到实战!
本文将带你深入探索LuatOS系统中log库的核心原理与实战技巧,通过代码示例解析日志管理、错误追踪及性能优化的最佳实践,助力全栈工程师构建更稳健的物联网应用。 今天,我们一起来认识LuatOS
解锁LuatOS-log库:全栈工程师的日志管理实战课!
针对全栈开发者设计的实战教程,本文聚焦LuatOS平台log库的高效使用,从基础配置到高级调试策略,手把手教你搭建可扩展的日志系统,提升项目维护效率。 今天,我们一起来认识LuatOS的log库
LOG300 具有集成式低噪声放大器的40MHz对数检测器技术手册
LOG300 是一款集成模拟前端 (AFE),由低噪声放大器 (LNA) 和对数检测器块组成。该器件支持高达 40MHz 的输入频率范围和 98dB 的典型动态范围,适用于需要宽动态电压范围和信号
HarmonyOS NEXT 原生应用/元服务-ArkTS代码调试Evaluate and log
开发者可以通过 Evaluate and log 能力在代码执行到断点行时打印开发者指定的表达式。
操作步骤
在需要打印表达式结果的地方设置断点。
右键断点,然后点击More按钮。
勾选
发表于 03-14 16:49
恩智浦解读Zephyr log系统的使用 Zephyr的shell和log功能介绍
Zephyr log系统的使用,在使用log前需要: 1. 修改proj.conf打开log功能: CONFIG_LOG =y 2. 编辑main.

log.c是什么?
评论