dpdk日志系统

    本篇文章从四个方面对dpdk日志系统进行剖析,分别是:

        1、dpdk日志框架

        2、内存池未初始化时的日志系统

        3、内存池已完成初始化的日志系统

        4、日志系统的使用

        下面分别对这四个方面进行分析:

一、dpdk日志框架        

        在分析dpdk源码时,难免存在有疑惑的地方,这个时候可以添加调试日志来消除的疑问。dpdk通过fopencookie接口自己实现了一个日志系统,下面我们来看下这个fopencookie是如何使用的。


        fopencookie会让我们注册四个接口,分别是读文件、写文件、定位文件的偏移、关闭文件接口。上图这个console_log_func结构,里面就包含了注册的四个接口。 那这些注册的接口是什么时候被调用呢。 通常情况下在进行系统调用情况下会调用这些接口。例如调用write函数写文件时,会调用到console_log_write接口; 在调用read函数读取文件内容时,会调用到console_log_read接口。

         gdb调试这个进程,可以验证上面这个调用的过程。rte_log开始写日志时,会进行write的系统调用,最终调用到console_log_write接口

二、内存池未初始化时的日志系统

        在进程刚启动的时候,从main函数开始到rte_eal_log_early_init调用前,如果需要打印些日志信息,只能够使用printf打印日志到屏幕, 而不能使用RTE_LOG函数来打印日志,否则进程将崩溃。

        只有rte_eal_log_early_init调用后,才能使用RTE_LOG来打印日志信息。这个时候由于内存池还没有初始化操作,是没有将日志缓存到内存中, 此时日志是实时打印到屏幕上的。从rte_eal_log_early_init接口到rte_eal_log_init之间,所有的RTE_LOG打日志操作,都是将日志立即打印到屏幕上,而不经过内存池处理。看下堆栈信息就能够验证这个问题,这个时候的打日志是通过ealy_log_write直接打印到屏幕上。

三、内存池已完成初始化的日志系统

        上面已经说了,从rte_eal_log_early_init接口到rte_eal_log_init之间,所有的RTE_LOG打日志操作,都是将日志立即打印到屏幕上,而不经过内存池处理。那rte_eal_log_init初始化之后呢? 在rte_eal_log_early_init接口与rte_eal_log_init之间,会进行内存池的初始化操作, 内存池初始化之后,以及rte_eal_log_init函数调用后,接下里也是通RTE_LOG来打印日志。日志除了打印到屏幕外,还会保存到内存中,然后定期将内存中的日志信息写入到文件保存(dpdk目前只提供了保存到文件的接口,通常在实际开发过程中由应用进程自己定期保存日志到文件)。从堆栈中可以看出,rte_eal_log_init初始化之后,打印日志是通过rte_log_add_in_history接口,而不再是ealy_log_write接口, 将日志信息保存到链表中,链表节点则是从内存池中获取的。

四、日志系统的使用

        在rte_eal_log_early_init函数初始化完成之后,可以通过RTE_LOG来打印日志。 可以指定要打印的模块,日志级别。例如打印table模块的日志,日志级别为ERR;   打印pipeline模块的日志,日志级别为info; 打印eal模块的日志,日志级别为debug

RTE_LOG(ERR, PMD,   		"hello! this is pmd module");
RTE_LOG(INFO, PIPELINE,		"hello! this is pipeline module");
RTE_LOG(DEBUG, EAL,		"hello! this is eal module");

        那dpdk支持打印哪些模块的日志呢?这个可以从rte_log.h宏定义可以看出,例如:

支持的日志类型
#define RTE_LOGTYPE_EAL     0x00000001 
#define RTE_LOGTYPE_MALLOC  0x00000002 
#define RTE_LOGTYPE_RING    0x00000004 

         每个模块又可以支持哪些日志级别呢?也是在rte_log.h中宏定义,例如:

支持的日志级别
#define RTE_LOG_ERR      4U  /**< Error conditions.                 */
#define RTE_LOG_WARNING  5U  /**< Warning conditions.               */
#define RTE_LOG_NOTICE   6U  /**< Normal but significant condition. */
#define RTE_LOG_INFO     7U  /**< Informational.                    */
#define RTE_LOG_DEBUG    8U  /**< Debug-level messages.             */

        从上面可以看出,dpdk支持很多模块的日志。那是不是只要随便调用RTE_LOG就能打印出日志呢? 答案肯定不行,dpdk自己实现了日志过滤器。只有用户调用rte_set_log_type设置了需要打印哪些模块,则这些模块才能打印出来,其他模块则过滤掉了,无法打印出来。例如调用rte_set_log_type设置了EAL,  MALLOC两个模块,则这两个模块可以打印出日志,但RTE_LOG(DEBUG,  PIPELINE, "hello pipeline")是无法打印出来了,因为没有设置PIPELINE这个模块。

        同样的,日志级别也是如此,通过rte_set_log_level来设置日志级别,小于这个日志级别的日志都可以打印出来。例如调用rte_set_log_level设置日志级别为RTE_LOG_CRIT,则小于ERR的日志级别:RTE_LOG_EMERG;RTE_LOG_ALERT;RTE_LOG_CRIT都可以打印出来,其他的日志级别就不行。

                       

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值