Boost.Log - how to configure a text sink backend to append to rotated files
Asked Answered
J

2

22

I have a sinks::text_file_backend sink. Say I already have a few rotated log files:

myLog001.log, myLog002.log and so on

I want the sink to keep writing to the last rotated file - myLog002.log, append to its contents and continue rotation from there on.

I have only managed to findkeywords::open_mode = append but this only appends on top of the existing myLogX files, making them larger and of course very hard to read.

Can this be done in Boost.Log?

Jezabella answered 7/12, 2011 at 16:35 Comment(0)
N
14

That functionality is built in to the text sink, and the documentation includes an example to set the file-name pattern and rules for rotating at certain sizes and times:

// The function registers file sink in the logging library
void init_logging()
{
    boost::shared_ptr< logging::core > core = logging::core::get();

    boost::shared_ptr< sinks::text_file_backend > backend =
        boost::make_shared< sinks::text_file_backend >(
            // file name pattern
            keywords::file_name = "file_%5N.log",
            // rotate the file upon reaching 5 MiB size...
            keywords::rotation_size = 5 * 1024 * 1024,
            // ...or at noon, whichever comes first
            keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0)
        );

    // Wrap it into the frontend and register in the core.
    // The backend requires synchronization in the frontend.
    typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
    boost::shared_ptr< sink_t > sink(new sink_t(backend));

    core->add_sink(sink);
}

There is apparently no way to make the library append to existing files with this setup. You should call backend->scan_for_files(); prior to constructing sink, as shown under the "Managing rotated files" heading in the documentation, but that only prevents the library from overwriting previous logs before they're due for cleanup.

When this topic arose on a development mailing list in February 2013, the library's author explained that adding support for appending would be a nontrivial change that couldn't be made under the current design.

Norine answered 7/12, 2011 at 18:29 Comment(3)
I use backend->scan_for_files(); in my program, but the program crashed when run into this code. Any idea about this?Caloyer
Rotation works, but what about appending? A program should append to the last log, for every subsequent run of the program, until the log file reach the rotation limits. This code creates a new log file on each run, and adding scan_for_files has no effect.Baseler
@WaterLin, see this: Why my application crashes on process termination when file sinks are used?Manslaughter
P
3

You have to specify the open_mode before use the text file. By default Boost.Log will use std::ios_base::trunc|std::ios_base::out as the open mode which obviously will truncate the old log file.

You can create text_file_backend instance with the following parameters:

    {
        boost::shared_ptr<sinks::text_file_backend> backend =
            boost::make_shared<sinks::text_file_backend>(
                keywords::file_name = logger_file_path,
                keywords::open_mode = std::ios_base::app|std::ios_base::out,
                keywords::rotation_size = 5 * 1024 * 1024,
                keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0));
        // Wrap it into the frontend and register in the core.
        // The backend requires synchronization in the frontend.
        typedef sinks::synchronous_sink<sinks::text_file_backend> sink_t;
        boost::shared_ptr<sink_t> sink(new sink_t(backend));
        sink->set_formatter(logFmt);
        core->add_sink(sink);
    }
Precontract answered 19/1, 2017 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.