boost::log基于时间的日志轮转未按预期触发问题求助
Boost.Log 时间触发日志轮转不自动执行的问题解决
Boost.Log的基于时间的日志轮转默认是被动触发的——只有当有新日志写入时,sink才会检查是否到达预设的轮转时间点。如果没有日志事件发生,检查逻辑不会被触发,自然不会执行轮转操作,这就是你遇到的问题。基于大小的轮转不受影响,因为它是在每次写入日志时检查文件大小是否达标。
解决方法:主动触发轮转检查
通过给文件sink添加周期性定时器,主动调用轮转检查方法,就能实现无日志写入时也能按时执行轮转。
代码修改示例
#include <boost/log/sinks/file_sink.hpp> #include <boost/log/sinks/async_frontend.hpp> #include <boost/asio/io_context.hpp> #include <boost/asio/steady_timer.hpp> #include <chrono> #include <thread> // 初始化文件sink(保留你原有的配置) auto sink = boost::log::sinks::file_sink_mt( boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(23, 59, 59), boost::log::keywords::rotation_size = 8 * 1024 * 1024, boost::log::keywords::auto_flush = true, boost::log::keywords::file_name = base_path_ + (base_path_.back() != '/' ? "/" : "") + base_name_ + (file_ext_.front() != '.' ? "." : "") + file_ext_, boost::log::keywords::target_file_name = base_path_ + (base_path_.back() != '/' ? "/" : "") + base_name_ + "_%Y-%m-%d_%H-%M-%S" + (file_ext_.front() != '.' ? "." : "") + file_ext_ ); // 创建ASIO上下文与定时器,用于主动检查轮转 boost::asio::io_context io_ctx; boost::asio::steady_timer rotation_timer(io_ctx); // 定义周期性检查函数 auto trigger_rotation_check = [&sink, &rotation_timer]() { // 主动触发sink的时间轮转检查 sink->rotate_on_timer(); // 设置下一次检查时间(这里设置为1分钟后,可根据需求调整) auto next_check = std::chrono::steady_clock::now() + std::chrono::minutes(1); rotation_timer.expires_at(next_check); rotation_timer.async_wait([&](const boost::system::error_code& ec) { if (!ec) { trigger_rotation_check(); } }); }; // 启动检查循环 trigger_rotation_check(); // 在后台线程运行ASIO事件循环,避免阻塞主线程 std::thread rotation_thread([&io_ctx]() { io_ctx.run(); });
关键说明
sink->rotate_on_timer():这是Boost.Log提供的主动触发时间轮转检查的方法,调用后会直接检查当前时间是否到达预设的轮转点,若满足条件则立即执行轮转。- 定时器周期:示例中设置为1分钟检查一次,既能保证不会错过23:59:59的轮转时间,又不会因过于频繁的检查占用过多系统资源。
- 线程安全:使用
file_sink_mt多线程安全版本的sink,配合后台线程运行ASIO循环,确保在多线程环境下的稳定性。
内容的提问来源于stack exchange,提问作者triccyx
相关产品推荐
相关产品推荐

