Search code examples
c++loggingboost

Boost.Log - how to configure text_file_backend with append and rotate


How to create a text_file_backend that appends to existing file but also has rotation? I do this, but a new file is created every time I run my program.

  1. App.log
  2. App.log00000
  3. App.log00001
  4. and so on and so forth ....

    boost::log::add_file_log
    (
        boost::log::keywords::auto_flush          = true,
        boost::log::keywords::target              = "Log",        
        boost::log::keywords::file_name           = "App.log",                                                  // file name pattern  eg: keywords::file_name = "app%m%d%Y_%H%M%S_%5N.log",    
        boost::log::keywords::open_mode           = std::ios::out | std::ios::app,                              // append mode 
        boost::log::keywords::rotation_size       = 10 * 1024 * 1024,                                           // rotate files every 10 MBytes
        boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),   // ...or at midnight
    .....
    

Is there something else I can try?

Thanks


Solution

  • With the target parameter you configured the target directory to be different from the directory where the log file is initially written (the file_name parameter), which means on rotation the file will be moved. Since the file name contains no placeholders that could differentiate the files, the new file clashes with the ones left in the target directory from previous rotations, and a counter suffix is appended to avoid the conflict.

    Appending only works when the sink backend opens the file identified by file_name and it already exists. It does not make the file appended to an existing file in the target directory on rotation, this is not possible. Since in your case the rotation moves the file away every time, appending will never happen.

    In order for appending and rotation both to work you have to ensure that (a) the previous file written by the sink backend is left in the same directory and has the same name as the new sink tries to open and (b) the file name contains some placeholders so that on every rotation a new file name is generated. These are conflicting requirements but some configurations can meet them. For example, you can configure the target directory to be the same as where the log file is written by the backend, the file name to contain a date and rotate each day on midnight.

    boost::log::add_file_log
    (
        boost::log::keywords::auto_flush          = true,
        boost::log::keywords::target              = "Log",        
        boost::log::keywords::file_name           = "Log/App_%Y%m%d.log",
        boost::log::keywords::open_mode           = std::ios::out | std::ios::app,
        boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0)
    );
    

    Note that file counters and rotation on file size do not work well with appending because they tend to violate one of the requirements I listed.