我正在使用boost :: log同时登录文件以及控制台。它的初始化如下:
void Init() {
logging::core::get()->set_filter
(
// set logging level to one of trace, debug, info, warning, error, fatal
logging::trivial::severity >= logging::trivial::trace
);
logging::add_common_attributes(); // enables timestamps and such
logging::add_file_log
(
keywords::file_name = logfile + "_%N.log",
keywords::rotation_size = 1024 * 1024 * 50, // 50MB log file max
// keywords::format = "[%TimeStamp%]: %Message%"
keywords::format = "%Message% #[%TimeStamp%]"
);
logging::add_console_log(std::cout,
keywords::format = "%Message%"
);
}
在我的程序中的某些点,我想手动更改日志文件。我可以在上面的代码中更改“logfile”字符串并再次调用Init(),但随后它继续写入旧的日志文件并启动新的日志文件,并开始在控制台日志上加倍输出。
我是否缺少某种相应的“remove_file_log”,或者手动告诉它停止记录到原始日志并转移到下一个日志?
答案 0 :(得分:4)
每次调用add_file_log
都会在日志记录核心中注册一个新的文件接收器,这会导致同时写入多个文件。现有的水槽没有更换。根据你真正想做的事情,你可以做很多事情。
首先,如果查看add_file_log
引用,您会注意到它返回指向创建的接收器的指针。当您希望停止使用该接收器时,可以将该指针传递给core::remove_sink
。在被销毁后,接收器将关闭它正在使用的日志文件。
typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
boost::shared_ptr< sink_t > g_file_sink;
void Init() {
// ...
g_file_sink = logging::add_file_log
(
keywords::file_name = logfile + "_%N.log",
keywords::rotation_size = 1024 * 1024 * 50, // 50MB log file max
keywords::format = "%Message% #[%TimeStamp%]"
);
// ...
}
void StopFileLogging() {
logging::core::get()->remove_sink(g_file_sink);
g_file_sink.reset();
}
其次,add_file_log
创建并返回的text_file_backend
能够旋转日志文件。如果您只想在程序的某些位置切换日志文件,那么这就是您可能正在寻找的内容。您可以将keywords::rotation_size
等命名参数添加到add_file_log
调用中,它们将用于在后端设置自动文件轮换。您也可以通过调用接收器后端上的text_file_backend::rotate_file
手动旋转文件。
void RotateLogFile() {
g_file_sink->locked_backend()->rotate_file();
}
请注意,在这种情况下,您不必从核心移除接收器;它在文件旋转后保持活动状态。