这两天发现了一个不错的开源项目,记录了学习经验。
对于基于嵌入式的应用程序开发,基本上离不开日志功能。这个轮子很多。log.c达到了最简单、立即可用的水平。
什么是Log.c?
简而言之,log.c是C语言的日志功能模块。
单击以查看大图
Log.c的一些特性:
代码简洁。c和。h文件,共200行。
设计优雅,打印日志的API只有一个。
提供将Log导入到其他目标的接口(例如,导入到文件中)。
提供实现线程安全的接口。
Log.c怎么用?
打印日志的API:
Log_trace(const char *fmt,);
Log_debug(const char *fmt,);
Log_info(const char *fmt,);
Log_warn(const char *fmt,);
Log_error(const char *fmt,);
Log_fatal(const char *fmt,);
它们都是log_log()的简单软件包,方式与printf()相同。
例如:
下面的示例将日志输出到标准输出和文件。
#include 'log.h '
Int main(int argc,char *argv[])
{
log _ set _ level(0);
log _ set _ quiet(0);
文件* fp1、* fp2
Fp1=fopen('' ab ');
If(fp1==空)
return-1;
Fp2=fopen('' ab ');
If(fp2==空)
return-1;
Log_add_fp(fp1、LOG _ INFO);
Log_add_fp(fp2、LOG _ DEBUG);
log _ debug(' debug ');
log _ info(' info ');
log _ warn(' warn ');
f close(fp2);
f close(fp1);
return 0;
}
运行:
$./example1
2:31:05 debug exam : debug
2:31:05 info exam : info
2:31:05 warn exam : warn
$ cat log_debug.txt
2022-05-08 2:31336005 debug exam : debug
2022-05-08 2:31336005 info exam : info
2022-05-08 2:31:05 warn exam : warn
$ cat log_in
2022-05-08 2:31336005 info exam : info
2022-05-08 2:31:05 warn exam : warn
【嵌入式物联网单片机学习】嵌入式物联网开发需要学习的东西比较多,可以添加下面的微信一起学习,100多克(全网最大)的学习资料包(不断更新),整理最新的学习路径思维导图。
各种学习小组、项目开发教程。还可以围观我朋友圈里的行业消息,每周技术大咖们直播解决问题,吹水。模板。
点击此处添加嵌入式物联网单片机学习。
线程安全信息:
Log.c代码较少,但考虑线程安全。使用示例如下:
#include 'log.h '
Pthread _ mutex _ t MUTEX _ LOG
Voidlog _ lock (bool lock,void * udata);
Int main()
{
log_set_level(0); log_set_quiet(0); pthread_mutex_init(&MUTEX_LOG, NULL); log_set_lock(log_lock, &MUTEX_LOG); /* Insert threaded application code here... */ log_info("I'm threadsafe"); pthread_mutex_destroy(&MUTEX_LOG); return 0; } void log_lock(bool lock, 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 是一个函数指针:。
typedef void (*log_LockFn)(bool lock, void *udata);
用户可以用它来指定自己想用的锁机制,例如 Pthread 的互斥量。
int level 用于保存当前的 log 等级,等级大于 level 的 log 才会被输出到标准输出。
bool quiet 用于打开、关闭 log 输出。
数组 Callbacks 用于保存多种输出方式,目前仅支持输出到标准输出和文件,有需要的话我们还可以将其扩展成输出到 syslog、网络等,每增加一种输出方式就是构造一个 Callback,成员回调函数 log_LogFn 负责真正地 log 输出功能:
typedef void (*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。
原文链接:
文章转载自:老吴嵌入式
文章来源于:简单到傻瓜都会用的日志库:log.c
原文链接:简单到傻瓜都会用的日志库:log.c
版权声明:本文来源于网络,免费传达知识,版权归原作者所有,如涉及作品版权问题,请联系我进行删除