今天我们给大家介绍SPDK Trace Log在Debug/Free build下针对特定模块的使用。
温馨提示:由于部分函数较长,建议使用电脑端或者手机横屏阅读~
一
什么是日志
日志,又称为Log,是我们开发人员的一款利器。我们通常在程序代码中插入一些特殊的输出代码,将程序当前的运行状态按需输出,以便于在无人值守的情况下记录信息,在事后对程序的处理过程进行分析。不管是在调试还是测试的阶段,日志都是我们的得力助手。
一个完善的日志系统不只是简单地在控制台输出,还具有以下几个特征:
-
使用一种方式就支持输出到多个目标,例如:控制台,文本文件,数据库等。
-
允许控制输出的级别,过滤输出的内容,而不需要大幅度修改日志程序。
-
使用简单,可以使用简单的语法来记录日志。
二
Linux内核中的日志系统函数和SPDK的封装
我们先来了解一下linux内核的三个系统函数openlog、syslog和closelog,这是一套系统日志写入接口。还有一个vsyslog,和syslog功能一样,只是参数格式不同。
2.1. openlog
openlog函数用来打开一个到系统日志记录程序的连接,打开之后就可以用syslog或vsyslog函数向系统日志里添加信息了。而closelog函数就是用来关闭此连接的。
通常来说,openlog需要在模块最开始指定,即限定了这个模块内都是一个facility的日志,SPDK里指定的是 LOG_LOCAL7。定义在/lib/event/app.c中,
1. void spdk_log_open(logfunc *logf)
2. {
3. if (logf) {
4. g_log = logf;
5. } else {
6. openlog("spdk", LOG_PID, LOG_LOCAL7);
7. }
8. }
参数说明:
LOG_PID,Include PID with each message,更多的是方便调试。
LOG_LOCAL0~LOG_LOCAL7, 为本地使用保留。
2.2. syslog
syslog 是Linux系统默认的日志守护进程。任何希望生成日志信息的程序都可以向 syslog 接口呼叫生成该信息,把日志消息发给系统程序syslogd去记录。
如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。
SPDK代码里是这样使用的:
1. void spdk_vlog(enum spdk_log_level level, const char *file, const int line, const char *func, const char *format, va_list ap)
2. {
3. ……
4. if (level <= g_spdk_log_level) {
5. syslog(severity, "%s:%4d:%s: *%s*: %s", file, line, func, spdk_level_names[level], buf);
6. }
7. }
日志打印效果看上去就是这样的,
00:10:27.002 [2021-12-23 04:27:19.499391] nvme_rdma.c:1778:nvme_rdma_ctrlr_create_qpair: *DEBUG*: RDMA requests
同时,syslog为每个事件赋予几个不同的优先级:
-
LOG_ERR,错误 信息
-
LOG_WARNING,警告信息
-
LOG_NOTICE,不是错误情况,但是可能需要处理
-
LOG_INFO,一般的打印信息
-
LOG_DEBUG,调试信息
SPDK也定义了类似的6个日志事件优先等级:
1. enum spdk_log_level {
2. SPDK_LOG_DISABLED = -1,/** All messages will be suppressed. */
3. SPDK_LOG_ERROR,
4. SPDK_LOG_WA