boost::log能否在每次应用程序运行时轮换日志文件?
Absolutely, Boost.Log can handle log rotation on each application startup—your current example just uses size-based rotation, so we need to adjust the setup to trigger rotation when the program launches.
Let's first look at your existing code
Your example configures rotation to happen when the log file hits 10MB (rotation_size = 10 * 1024 * 1024), and it appends to existing files on restart thanks to open_mode = (std::ios::out | std::ios::app). This won't automatically rotate on startup by default.
Here are a few ways to implement startup-time rotation:
1. Force immediate rotation after initializing the sink
The simplest approach is to manually trigger rotation right after setting up your file sink. This tells Boost.Log to create a new log file as soon as the program starts, regardless of the existing file's size:
#include <boost/log/sinks/text_file_backend.hpp> #include <boost/log/utility/setup/file.hpp> #include <boost/log/trivial.hpp> #include <boost/log/core.hpp> #include <boost/log/expressions.hpp> namespace logging = boost::log; namespace sinks = logging::sinks; namespace keywords = logging::keywords; void init() { // Create the file sink with your original settings auto sink = logging::add_file_log( keywords::file_name = "sample_%N.log", keywords::rotation_size = 10 * 1024 * 1024, keywords::open_mode = (std::ios::out | std::ios::app), keywords::format = "[%TimeStamp%]: %Message%" ); // Force rotation immediately on startup sink->locked_backend()->rotate(); logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info); } int main(int, char*[]) { init(); logging::add_common_attributes(); using namespace logging::trivial; src::severity_logger<severity_level> lg; BOOST_LOG_SEV(lg, info) << "Application started successfully"; return 0; }
Note: On the first run, this might create an empty sample_0.log before rotating to sample_1.log. If you want to avoid that, you can check for existing log files first (see option 2).
2. Start rotation from the next available index (cleaner first-run behavior)
If you want to avoid empty initial files, you can scan the directory for existing sample_%N.log files, find the highest index, and start rotation from there:
#include <boost/log/sinks/text_file_backend.hpp> #include <boost/log/utility/setup/file.hpp> #include <boost/log/trivial.hpp> #include <boost/log/core.hpp> #include <boost/log/expressions.hpp> #include <boost/filesystem.hpp> namespace logging = boost::log; namespace sinks = logging::sinks; namespace keywords = logging::keywords; namespace fs = boost::filesystem; void init() { unsigned int max_log_index = 0; // Scan current directory for existing sample logs for (const auto& entry : fs::directory_iterator(".")) { if (fs::is_regular_file(entry.status())) { std::string filename = entry.path().filename().string(); if (filename.starts_with("sample_") && filename.ends_with(".log")) { // Extract the numeric part between "sample_" and ".log" std::string index_str = filename.substr(7, filename.size() - 7 - 4); try { unsigned int index = std::stoul(index_str); if (index > max_log_index) { max_log_index = index; } } catch (...) { // Skip files with invalid numbering continue; } } } } auto sink = logging::add_file_log( keywords::file_name = "sample_%N.log", keywords::rotation_size = 10 * 1024 * 1024, keywords::open_mode = (std::ios::out | std::ios::app), keywords::format = "[%TimeStamp%]: %Message%", keywords::initial_index = max_log_index // Start from the highest existing index ); // Rotate to the next index sink->locked_backend()->rotate(); logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info); } int main(int, char*[]) { init(); logging::add_common_attributes(); using namespace logging::trivial; src::severity_logger<severity_level> lg; BOOST_LOG_SEV(lg, info) << "Application started successfully"; return 0; }
This ensures that each startup creates a new log file with the next sequential number, no empty files left behind.
3. Custom rotation policy (for advanced needs)
If you need more control over when rotation happens, you can implement a custom rotation policy by inheriting from logging::sinks::file::rotation_policy. This lets you define your own trigger conditions (like checking if it's the first run of the program). This is overkill for most cases, but useful if you have complex rotation rules.
Key takeaway
Boost.Log doesn't have a built-in "rotate on startup" flag, but with a few lines of code—either forcing immediate rotation or pre-scanning for existing logs—you can easily implement this behavior.
内容的提问来源于stack exchange,提问作者Viktor

