Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost.Log的通道层次结构进行严重性和接收器过滤_C++_Logging_Boost_Boost Log - Fatal编程技术网

C++ 使用Boost.Log的通道层次结构进行严重性和接收器过滤

C++ 使用Boost.Log的通道层次结构进行严重性和接收器过滤,c++,logging,boost,boost-log,C++,Logging,Boost,Boost Log,我已经学习Boost.Log一段时间了,我相信现在是我将代码库从log4cxx转换到Boost.Log的时候了。我相信Boost.Log的设计和实现将显著提高我的代码维护和使用率。我知道Boost.Log常见问题有一个 对于分层记录器,在当前库设计中不需要此功能。它在log4j中提供的一个主要好处是确定日志记录将在其中创建的附加器(根据该库,是接收器) 最终该库通过过滤实现相同的结果 我理解概念上的等价性,我不想让Boost.Log进入log4j/log4cxx。相反,我的问题是:如何使用Boo

我已经学习Boost.Log一段时间了,我相信现在是我将代码库从log4cxx转换到Boost.Log的时候了。我相信Boost.Log的设计和实现将显著提高我的代码维护和使用率。我知道Boost.Log常见问题有一个

对于分层记录器,在当前库设计中不需要此功能。它在log4j中提供的一个主要好处是确定日志记录将在其中创建的附加器(根据该库,是接收器) 最终该库通过过滤实现相同的结果

我理解概念上的等价性,我不想让Boost.Log进入log4j/log4cxx。相反,我的问题是:如何使用Boost.Log来获得当前从log4cxx使用的相同功能?特别是,我想为日志源或通道层次结构中的特定节点设置严重性阈值和接收器。例如,我有由
libA.moduleB.componentC.logD
组织的日志源,层次结构中的级别由点分隔
。使用log4cxx,可以将
libA
的总体阈值设置为INFO,使用更具体的记录器
libA.moduleB
,具有调试阈值

libA.threshold=INFO
libA.moduleB.threshold=DEBUG
类似地,可以将接收器附加到层次结构中的任意节点

我相信Boost.Log也可以提供类似的功能,但我需要关于如何实际实现这一功能的帮助/指导。另外,我相信其他希望从其他框架过渡到Boost.Log的人也会有同样的问题

非常感谢您的评论。

Boost.Log接收器(写入日志文件的对象)和记录器(应用程序通过其发出日志记录的对象)没有直接连接,任何接收器都可能从任何记录器接收日志消息。为了使来自某些记录器的记录仅在特定接收器中显示,您必须在接收器中安排过滤器,以便对不应该接收它们的接收器抑制不必要的记录,并将其传递给其他接收器。为了区分不同记录者的记录,记录者必须为他们制作的每个记录添加不同的属性。通常,这是通过以下方式实现的-记录器将附加一个通道属性,该属性可用于在过滤器、格式化程序或接收器中标识记录器。通道可以与其他属性一起使用,例如严重性级别。但必须注意的是,通道和严重性级别是正交的,任何通道都可能有任何级别的记录。在过滤器中分别分析不同属性的值

因此,例如,如果希望将通道A中的记录写入文件A.log,并将通道B中的记录写入文件B.log,则必须创建两个接收器-每个文件一个接收器,并相应地设置其过滤器

BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_channel, "Channel", std::string)

logging::add_file_log(
    keywords::file_name = "A.log",
    keywords::filter = a_channel == "A");

logging::add_file_log(
    keywords::file_name = "B.log",
    keywords::filter = a_channel == "B");
请参阅关于和的文档。现在您可以为每个通道创建记录器,并且日志记录将通过过滤器路由到接收器

typedef src::severity_channel_logger< severity_level, std::string > logger_type;

logger_type lg_a(keywords::channel = "A");
logger_type lg_b(keywords::channel = "B");

BOOST_LOG_SEV(lg_a, info) << "Hello, A.log!";
BOOST_LOG_SEV(lg_b, info) << "Hello, B.log!";
现在,设置接收器将更改如下,以使用新过滤器:

logging::add_file_log(
    keywords::file_name = "A.log",
    keywords::filter = phoenix::bind(&my_filter, a_severity.or_none(), a_channel.or_none(), hierarchy_A));

logging::add_file_log(
    keywords::file_name = "B.log",
    keywords::filter = phoenix::bind(&my_filter, a_severity.or_none(), a_channel.or_none(), hierarchy_B));

这里的
hierarchy\u A
hierarchy\u B
是用于存储两个日志文件的不同通道的严重性阈值的数据结构。

感谢您的回答。我感谢你的帮助,让我开始。通道层次结构对我来说很重要,因此我将不得不承担额外的复杂性。根据您给我的大纲,我的问题似乎可以归结为编写数据结构和逻辑来支持阈值和接收器过滤器,子节点继承自父节点。使用log4j,他们强调如何有一个最佳方案来实现这一点。你知道是否有人使用Boost.Log库实现了类似的方案吗?不,我不知道有人这样做。但是,为严重性阈值创建数据结构看起来并不困难-您可以使用许多嵌套的
std::map
/
std::unordered_map
或Boost.PropertyTree()来实现它,已经对文本进行了序列化/反序列化。如何定义通道层次结构?@Andreyesmashev-是否可以使用lambda表达式(不含
phoenix::bind
)在
add\u file\u log
调用中定义
filter
?如果是,您能给我们举个例子吗?过滤器只是一个具有特定签名的函数对象:
bool(boost::log::attribute\u value\u set const&)
。不管该函数对象是用Boost.Phoenix、C++11 lambda还是普通函数实现的。如果它支持该签名,则可以将其设置为筛选器。例如:
keywords::filter=[](boost::log::attribute_value_set const&attrs){return true;}
logging::add_file_log(
    keywords::file_name = "A.log",
    keywords::filter = phoenix::bind(&my_filter, a_severity.or_none(), a_channel.or_none(), hierarchy_A));

logging::add_file_log(
    keywords::file_name = "B.log",
    keywords::filter = phoenix::bind(&my_filter, a_severity.or_none(), a_channel.or_none(), hierarchy_B));