• Fast DDS之Logging


    log格式如下:

    <Timestamp> [<Category> <Verbosity Level>] <Message> (<File Name>:<Line Number>) -> Function <Function Name>
    # 如:
    2020-05-27 11:45:47.447 [DOCUMENTATION_CATEGORY Error] This is an error message (example.cpp:50) -> Function main
    
    • 1
    • 2
    • 3

    用户通过三个宏记录Log:

    • EPROSIMA_LOG_INFO: Log::Kind::Info verbosity.
    • EPROSIMA_LOG_WARNING: Log::Kind::Warning verbosity.
    • EPROSIMA_LOG_ERROR: Log::Kind::Error verbosity.
      这三个宏带两个参数,category 和具体的log字符串,如下:
    EPROSIMA_LOG_INFO(DOCUMENTATION_CATEGORY, "This is an info message");
    EPROSIMA_LOG_WARNING(DOCUMENTATION_CATEGORY, "This is an warning message");
    EPROSIMA_LOG_ERROR(DOCUMENTATION_CATEGORY, "This is an error message");
    
    • 1
    • 2
    • 3

    配置

    log输出内容

    • Timestamp:时间,格式为 YYYY-MM-DD hh:mm:ss.sss,固定格式,且不能关闭
    • Category:category可以用来过滤log,也能配置和关闭
    • Verbosity Level:提供了三种级别:
      • Log::Kind::Error: Used to log error messages.
      • Log::Kind::Warning: Used to log error and warning messages.
      • Log::Kind::Info: Used to log error, warning, and info messages.
        默认为 Log::Kind::Error,可以通过函数 Log::SetVerbosity 重新设置。
    // Set log verbosity level to Log::Kind::Info
    Log::SetVerbosity(Log::Kind::Info);
    
    // Get log verbosity level
    Log::Kind verbosity_level = Log::GetVerbosity();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • Message:要记录的log信息。
    • 文件信息:文件名和行号,可以通过Log::ReportFilenames()关闭
    // Enable file name and line number reporting
    Log::ReportFilenames(true);
    
    // Disable file name and line number reporting
    Log::ReportFilenames(false);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • function name:记录函数名,可以通过函数Log::ReportFunctions()开关该功能。
    // Enable function name reporting
    Log::ReportFunctions(true);
    
    // Disable function name reporting
    Log::ReportFunctions(false);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注册Comsumers

    支持0或多个consumers,通过函数 Log::RegisterConsumer() 注册,Log::ClearConsumers()清空所有comsumers。

    // Create a FileConsumer consumer that logs entries in "archive.log"
    std::unique_ptr<FileConsumer> file_consumer(new FileConsumer("archive.log"));
    // Register the consumer. Log entries will be logged to STDOUT and "archive.log"
    Log::RegisterConsumer(std::move(file_consumer));
    // Clear all the consumers. Log entries are discarded upon consumption.
    Log::ClearConsumers();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置log级别

    三种级别:

    • Log::Kind::Error: Used to log error messages.
    • Log::Kind::Warning: Used to log error and warning messages.
    • Log::Kind::Info: Used to log error, warning, and info messages.
      默认为 Log::Kind::Error,可以通过函数 Log::SetVerbosity 重新设置。
    // Set log verbosity level to Log::Kind::Info
    Log::SetVerbosity(Log::Kind::Info);
    
    // Get log verbosity level
    Log::Kind verbosity_level = Log::GetVerbosity();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    重置配置

    通过函数 Log::Reset() 重置到默认的配置,具体为:

    • Setting Verbosity Level to Log::Kind::Error.
    • Disabling File Context component.
    • Enabling Function Name component.
    • Clear all Filters.
    • Clear all consumers and reset the default consumer according to CMake option LOG_CONSUMER_DEFAULT.

    XML配置

    过滤

    除了Verbosity Level,DDS提供了三种不同的过滤条件,都使用std::regex_search()过滤:

    • Category Filtering:使用函数Log::SetCategoryFilter设置过滤规则:
    // Set filter using regular expression
    Log::SetCategoryFilter(std::regex("(CATEGORY_1)|(CATEGORY_2)"));
    
    // Would be consumed
    EPROSIMA_LOG_ERROR(CATEGORY_1, "First log entry");
    // Would be consumed
    EPROSIMA_LOG_ERROR(CATEGORY_2, "Second log entry");
    // Would NOT be consumed
    EPROSIMA_LOG_ERROR(CATEGORY_3, "Third log entry");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出以下内容:

    2020-05-27 15:07:05.771 [CATEGORY_FILTER_1 Error] First log entry -> Function main
    2020-05-27 15:07:05.771 [CATEGORY_FILTER_2 Error] Second log entry -> Function main
    
    • 1
    • 2
    • File Name Filtering:函数Log::ReportFilenames设置文件名过滤
      以代码文件example.cpp为例:
    // Enable file name and line number reporting
    Log::ReportFilenames(true);
    
    // Set filter using regular expression so filename must match "example"
    Log::SetFilenameFilter(std::regex("example"));
    // Would be consumed
    EPROSIMA_LOG_ERROR(CATEGORY, "First log entry");
    
    // Set filter using regular expression so filename must match "other"
    Log::SetFilenameFilter(std::regex("other"));
    // Would NOT be consumed
    EPROSIMA_LOG_ERROR(CATEGORY, "Second log entry");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出如下log:

    2020-05-27 15:07:05.771 [CATEGORY Error] First log entry (example.cpp:50) -> Function main
    
    • 1
    • Content Filtering:Log::SetErrorStringFilter函数用来设置过滤。举例如下:
      log消息中包含"First"的内容:
    // Set filter using regular expression so message component must match "First"
    Log::SetErrorStringFilter(std::regex("First"));
    // Would be consumed
    EPROSIMA_LOG_ERROR(CATEGORY, "First log entry");
    // Would NOT be consumed
    EPROSIMA_LOG_ERROR(CATEGORY, "Second log entry");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出以下内容:

    2020-05-27 15:07:05.771 [CATEGORY Error] First log entry -> Function main
    
    • 1

    重置log过滤

    使用函数 Log::Reset(),重置内容包括以下:

    • Setting Verbosity Level to Log::Kind::Error.
    • Disabling File Context component.
    • Enabling Function Name component.
    • Clear all Filters.
    • Clear all consumers and reset the default consumer according to CMake option LOG_CONSUMER_DEFAULT.

    Comsumers

    提供了三种不同的comsumers对应到三种输出流:

    StdoutConsumer

    标准输出,默认的输出方式。log模块的cmake中LOG_CONSUMER_DEFAULT 值为AUTO,STDOUT,或者没有被其他设置时。

    // Create a StdoutConsumer consumer that logs entries to stdout stream.
    std::unique_ptr<StdoutConsumer> stdout_consumer(new StdoutConsumer());
    
    // Register the consumer.
    Log::RegisterConsumer(std::move(stdout_consumer));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    StdoutErrConsumer

    StdoutErrConsumer使用Log::Kind过滤log。大于等于Log::Kind级别的log会输出到STDERR中,其他的输出到STDOUT中。默认情况下阈值为Log::Kind::Warning。函数StdoutErrConsumer::stderr_threshold可以修改默认阈值。如果cmake中的LOG_CONSUMER_DEFAULT 指定为STDOUTERR,默认log consumer会使用StdoutErrConsumer。

    // Create a StdoutErrConsumer consumer that logs entries to stderr only when the Log::Kind is equal to ERROR
    std::unique_ptr<StdoutErrConsumer> stdouterr_consumer(new StdoutErrConsumer());
    stdouterr_consumer->stderr_threshold(Log::Kind::Error);
    
    // Register the consumer
    Log::RegisterConsumer(std::move(stdouterr_consumer));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    FileConsumer

    可以将log输入到文件中,并且可以使用write或append模式,清空写或追加log到log文件中。

    // Create a FileConsumer consumer that logs entries in "archive_1.log", opening the file in "write" mode.
    std::unique_ptr<FileConsumer> write_file_consumer(new FileConsumer("archive_1.log", false));
    
    // Create a FileConsumer consumer that logs entries in "archive_2.log", opening the file in "append" mode.
    std::unique_ptr<FileConsumer> append_file_consumer(new FileConsumer("archive_2.log", true));
    
    // Register the consumers.
    Log::RegisterConsumer(std::move(write_file_consumer));
    Log::RegisterConsumer(std::move(append_file_consumer));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    禁用log

    可以通过以下CMake 中的编译宏,在编译阶段禁用log:

    • EPROSIMA_LOG_INFO:将LOG_NO_INFO 设置为 ON或定义宏 HAVE_LOG_NO_INFO值为1.
    • EPROSIMA_LOG_WARNING:将LOG_NO_WARNING 值设为 ON或者定义宏HAVE_LOG_NO_WARNING 为1.
    • EPROSIMA_LOG_ERROR:将LOG_NO_ERROR 值设为 ON或定义宏HAVE_LOG_NO_ERROR 值为1.

    代码

    类图
    在这里插入图片描述
    时序图
    在这里插入图片描述
    Fast DDS中的DBQueue(Double Buffer Queue)使用两个buffer是为了提高数据处理的效率。当一个buffer被用来填充新的数据时,另一个buffer可以被用来处理和发送已经填充好的数据。这样,填充数据和处理数据这两个操作就可以并行进行,互不干扰。这种设计通常被称为"双缓冲"(Double Buffering)

  • 相关阅读:
    短链接系统如何设计
    如何用Python敲出樱花开放(附零基础学习资料)
    jdk中bin目录详解
    Adaboost 算法【python,机器学习,算法】
    el-upload添加请求头
    vue怎么跳转页面?
    WebGL笔记:使用鼠标绘制多个线条应用及绘制动感线性星座
    Google开源offload友好协议PSP,目前已正式部署到生产中
    字节二面,差点倒在了MySQL上面
    猿创征文 | 【Java进阶】详解抽象类及常用接口
  • 原文地址:https://blog.csdn.net/u010378559/article/details/133798153