提升日志 - 处理关机情况
boost log - handling power off scenario
我已经使用boost 1.63实现了一个全局记录器。这是初始化:
BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt< severity_level >)
{
typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
boost::shared_ptr< file_sink > sink(new file_sink(
keywords::file_name = "/var/log/testApp/%Y%m%d_%H%M%S_testApp.log",
keywords::rotation_size = 5 * 1024 * 1024,
keywords::auto_flush = true));
sink->locked_backend()->set_file_collector(sinks::file::make_collector(
keywords::target = "/var/log/testApp/oldLogs",
keywords::max_size = 5 * 1024 * 1024 * 2,
keywords::min_free_space = 5 * 1024 * 1024 * 2,
keywords::max_files = 2));
sink->locked_backend()->scan_for_files();
sink->set_formatter(
expr::format("[%1%]<%2%> : %3%") %
expr::attr< boost::posix_time::ptime >("TimeStamp") %
expr::attr< severity_level >("Severity") %
expr::smessage);
logging::core::get()->add_sink(sink);
logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
src::severity_logger_mt< severity_level > slg;
return slg;
}
当程序意外完成时(例如sudo kill -9 pid或关闭电源),日志文件不会移动到oldLogs目录(当程序再次运行时也是如此),并且/var/log/testApp目录可能包含许多日志文件。
是否有可能处理这种情况?
是否可以处理这种情况?
只能通过离线手段。例如,您可以在下次引导时自动运行脚本,将半写的日志文件移动到目标目录。或者,您可以在下次启动应用程序时执行此操作。在这种情况下,如果在追加模式下打开日志文件(即keywords::open_mode = std::ios::app
通过将命名参数传递给接收器构造函数),然后立即在接收器后端调用rotate_file
,则 Boost.Log 可以帮助您。这样,非空日志文件将在应用程序启动时轮换,尽管您将无法实际追加到日志文件。
更新:
我注意到您在日志文件名中使用了时间戳。在这种情况下,使用 Boost.Log 轮换日志文件的方法将不起作用,因为下次应用程序启动时,库可能会打开一个不同名称的文件。如果时间戳是必不可少的,剩下的唯一替代方案就是脚本。
为了补充安德烈·谢马舍夫所说的话,您还需要做以下事情:
- 从日志文件中删除时间戳(例如
keywords::file_name = "app.log"
),以便在使用keywords::open_mode = std::ios::app
时打开相同的文件,而是仅为旋转的文件放置时间戳(例如keywords::target_file_name = "app_%Y%m%d_%H%M%S.log"
) - 在调用
rotate_file()
之前,如果您的应用程序刚刚启动,则需要记录一些内容,否则不会发生任何事情,因为日志文件尚未打开。 - 您应该设置
keywords::enable_final_rotation = false
,以便如果您没有正确关闭机器和应用程序而不是power off
,则不会旋转,因为无论如何您都会在下次启动时进行轮换 -rotate_file()
将轮换non-empty
日志这一事实无关紧要,因为您首先需要记录一些内容以打开日志文件,以便rotate_file()
首先工作, 这是一个永远不会发生的场景。
有关更多详细信息,请查看此问题。
相关文章:
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 函数中堆分配的效果与缺少堆分配的情况
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么这个音频包络不能通过开关的情况?
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 提升日志 - 处理关机情况