Okies... I had to dig through the boost code a bit (but not too much), and I found this, which seems to work:
When you call add_file_log(strLogFilename)
it returns a shared_ptr<sink>
where sink
is your type of sink (e.g., shared_ptr< synchronous_sink< text_file_backend > >
). If you instead create your sink "manually" then of course you have a pointer to it as well... It seems the sinks and backend both have a .flush()
method. I'm not sure offhand how you directly get a copy of the backend to call its flush, but the flush on the sink seems to simply call the flush on its backend(s), so that works. Here's some example code of what I found to work for me:
shared_ptr< synchronous_sink< text_file_backend > > pLogSink = add_file_log(strLogFilaname);
BOOST_LOG_TRIVIAL(debug) << "Boost log!";
// other work goes here
BOOST_LOG_TRIVIAL(debug) << "About to fork...";
if (pLogSink)
pLogSink->flush();
pid_t pid = fork();
if (pid < 0)
// handle error
else if (pid > 0)
exit(EXIT_SUCCESS); // parent terminates
assert(0 == pid); // child continues
BOOST_LOG_TRIVIAL(debug) << "Fork succeeded!";
Using this method, I now see each log message only once. Of course, bear in mind this warning about mixing Boost.Log with fork()... http://boost-log.sourceforge.net/libs/log/doc/html/log/rationale/fork_support.html
In my example, it's safe only because the parent process immediately exits after forking without touching the log at all (after the fork). Thus there isn't any contention for the log.
Despite the limitations, I can see using this in a few cases: 1) daemonizing a process (which is what I'm trying to do here, actually), 2) fork-exec pattern (which does work fine with Boost.Log, according to the above URL), or 3) child process immediately closes the file sink and opens a new sink for the log that points to a different file (from the one the parent process is using) - I think this third case should be safe.