TIL - Split streams with boost::tee_device

TIL - Split streams with boost::tee_device

TIL, Today I Learned, is more of a "I just figured this out: here are my notes, you may find them useful too" rather than a full blog post

Split streams could be useful if you want the same output to appear in more than one stream at once. Boost support tee_device, which works pretty much as the tee(1) [1] command line tool. Everything written to that device is splitted up and written into two streams. Think of the letter T.


Here is an example of how to let everything written to cout and also be logged into a file. This is achieved by change the streambuffer for cout to instead use the logger stream:

    #include <fstream>
    #include <iostream>

    #include <boost/iostreams/tee.hpp>
    #include <boost/iostreams/stream.hpp>

    using std::ostream;
    using std::ofstream;
    using std::cout;
    using std::endl;

    using boost::iostreams::tee_device;
    using boost::iostreams::stream;

    // Create typedefs to avoid too long type declarations later on
    typedef tee_device<ostream, ofstream> TeeDevice;
    typedef stream<TeeDevice> TeeStream;

    int main()
        // Create streams and connect them to a file and stdout
        ofstream ofs("stdout.log");
        ostream tmp(cout.rdbuf());

        TeeDevice logdevice(tmp, ofs);
        TeeStream logger(logdevice);

        // Set streambuffer for cout 

        // Make some logs
        cout << "Log output to both stdout and file." << endl;

Compile and test

    [08:35:24]marcus@goliat:~/tmp/tee$ g++ main.cpp -o main && ./main
    Log output to both stdout and file.

    [08:56:09]marcus@goliat:~/tmp/tee$ cat stdout.log 
    Log output to both stdout and file.