转载于:https://blog.csdn.net/u010378559/article/details/133798153
感谢分享!
目录
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");
配置
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();
// Enable file name and line number reporting
Log::ReportFilenames(true);
// Disable file name and line number reporting
Log::ReportFilenames(false);
// Enable function name reporting
Log::ReportFunctions(true);
// Disable function name reporting
Log::ReportFunctions(false);
注册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();
设置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();
重置配置
通过函数 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”);
输出以下内容:
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
- 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”);
输出如下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");
输出以下内容:
2020-05-27 15:07:05.771 [CATEGORY Error] First log entry -> Function main
重置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));
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));
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));
禁用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)