提升C++中的日志记录和"类对象"日志记录行为
Boost Logging and 'Object-like' Logging Behaviour in C++
我在C++中搜索日志库已经好几天了,但不知何故,我对现有的解决方案(如boost logging或Pantheios)不太满意。最初我是一名Java开发人员。我想有一个日志库,带有一个行为更像对象的记录器。我想做以下事情:
- 创建日志记录对象
Logger(filepath, filename)
的实例 - 并使用
log(serverity, message)
方法在文本文件中记录不同的消息
这些功能的突出问题是,我事先不知道这些日志记录对象中有多少个,也不知道这些文件是否具有相同的文件路径。也许我可以用boost来处理这个问题,但我在文档的"文本多文件后端"部分没有得到这个例子。特别是这个例子中的代码片段会做什么:
片段1。
// Set up the file naming pattern
backend->set_file_name_composer
(
sinks::file::as_file_name_composer(expr::stream << "logs/" << expr::attr< std::string >("RequestID") << ".log")
);
片段2。
// Set the formatter
sink->set_formatter
(
expr::stream
<< "[RequestID: " << expr::attr< std::string >("RequestID")
<< "] " << expr::smessage
);
这个代码在我的脑海中提出了4个问题:
- 这是否意味着我只需要设置属性RequestID,然后记录器就会决定将消息放在哪个文件中?我该怎么做
- 使用boost是否可以将日志文件保存在不同的路径中
- 如果不同的线程访问同一个文件会发生什么
- init_logging()中的这段代码会影响boost日志记录库在应用程序范围内的行为吗?这是由某种。。。全局变量
也许我的想法太天真了。有没有一种方法可以得到我在帖子开头提到的东西?
如果你是Boost.Log的新手,你应该先了解一下库的设计,它与Java有很大的不同。尽管存在差异,但可以以与log4j类似的方式配置库,这个答案将有助于您入门。
现在,回答您的问题:
- 这是否意味着我只需要设置属性RequestID,然后记录器就会决定将消息放在哪个文件中?我该怎么做
在text_multifile_backend
的特定情况下,接收器将决定将每个日志记录写入哪个文件。set_file_name_composer
调用设置了一个组成日志文件名的函数对象,正如您所看到的,它涉及RequestID属性。当然,您可以使用任何您喜欢的属性,包括通道。您还应该知道,text_multifile_backend
并不是实现您想要的目标的唯一方法(也可能不是最有效的方法)。如果不同日志文件的数量有限,通常最好添加几个文本文件接收器,每个文件一个,并设置筛选,以便每个接收器接收自己的日志记录。我在上面链接的答案中描述了这种方法。
关于添加属性,根据用例和您要将其添加到的属性集,有不同的方法。在通道的情况下,此属性由记录器自动提供,您只需使用通道名称创建记录器,通过该记录器创建的每个日志记录都将其附加为属性。您所指向的示例中的RequestID属性可以以任何可能的方式添加。以下是几个常见的例子:
- 它可以手动添加到记录器中。如果您创建了一个用于处理请求的记录器(广义上讲,无论"请求"在您的应用程序中是什么意思),并通过该记录器写入与请求处理相关的所有日志消息,则这是典型的情况
- 它可以作为作用域属性添加到记录器中。如果您没有针对每个请求的专用记录器,但在某个地方有一个通用记录器,用于编写与请求处理相关的日志,那么这将非常有用
- 它可以作为作用域属性添加到线程特定的属性中。如果请求处理涉及程序不同部分的多个记录器,但在给定的时间点只有一个线程(当前线程)在处理特定请求,这将有所帮助。其他线程可能正在处理其他请求,并设置自己的线程特定属性——它们不会干扰
- 使用boost是否可以将日志文件保存在不同的路径中
当然。正如我所说,这可以通过向核心添加多个文件接收器来实现。从本质上讲,text_multifile_backend
已经能够写入多个文件。
- 如果不同的线程访问同一个文件会发生什么
Boost.Log支持多线程。在接收器级别上,接收器前端实现线程同步。例如,synchronous_sink
前端将阻止竞争线程同时写入单个文件。日志记录可以同时写入不同的接收器。
记录器也有单线程和多线程版本,后者进行额外的锁定以保护其内部结构免受并发访问。然而,这种保护并没有在接收器上扩展(即,即使您使用_mt
记录器,接收器前端仍然必须同步线程)。
- init_logging()中的这段代码会影响boost日志记录库在应用程序范围内的行为吗?这是由某种。。。全局变量
Boost.Log中有很多单身汉,是的。最值得注意的是,日志核心,在其中注册所有接收器以及全局和线程特定的属性。添加一个新的接收器将对整个应用程序产生影响,因为所有记录器的记录都将开始进入该接收器(这就是为什么在将接收器添加到核心之前通常应该配置它)。记录器本身与接收器无关,日志记录最终出现在哪个接收器中仅由筛选器定义。但正如我所提到的,在属性和过滤器的帮助下,可以将记录器和接收器关联起来,并以相关的方式管理它们。您必须编写一个包装类,提供您所描述的接口以及Boost。日志记录器创建并配置相应的接收器。
我认为您需要log4cxx日志库。当您将其写入日志文件时,它会确定日志级别
这是你入门的参考资料。http://www.yolinux.com/TUTORIALS/Log4cxx.html
- 如何实现具有多个平台__FILE__和__LINE__信息的 C/C++ 可变参数日志记录宏?
- C++ 中混合二进制/文本日志记录的最佳做法
- 轻松日志记录++如何避免多个初始化
- 使用字符串流加速 std::cout 日志记录
- 我的游戏引擎的 spdlog 日志记录出现奇怪的"unresolved external symbol"错误
- 使用 #define 进行跟踪日志记录以避免性能问题
- 如何在代码中启用/禁用 spdlog 日志记录?
- 我正在尝试用 c++ 制作一个日志记录框架,但信息没有传递给记录器的子组件,我做错了什么?
- 使用 Python、ROS 和 C++ 进行日志记录
- C++日志记录类实例标识符
- 如何在C++中重载<<线程安全日志记录的运算符?
- 在 C++17 中将无限参数传递给日志记录函数
- 配置 log4cpp 日志记录级别优先级
- 如何使用 Boost V2 1.70 日志记录库在第一个索引(例如 logtrail01.txt)保留最新的日志文件名?
- 如何将日志记录写入Visual Studio输出窗口?
- 使用现有日志记录库 (C++) 限制日志大小
- "正在初始化":无法从"事件日志记录 *"转换为"事件日志记录 []"
- 提升日志记录text_file_backend没有wchar_t版本?
- 多线程应用程序中的独立日志记录
- C++类似cout的函数,将数据写入文件(日志记录)