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:
1 #include <fstream>
2 #include <iostream>
3
4 #include <boost/iostreams/tee.hpp>
5 #include <boost/iostreams/stream.hpp>
6
7 using std::ostream;
8 using std::ofstream;
9 using std::cout;
10 using std::endl;
11
12 using boost::iostreams::tee_device;
13 using boost::iostreams::stream;
14
15 // Create typedefs to avoid too long type declarations later on
16 typedef tee_device<ostream, ofstream> TeeDevice;
17 typedef stream<TeeDevice> TeeStream;
18
19 int main()
20 {
21 // Create streams and connect them to a file and stdout
22 ofstream ofs("stdout.log");
23 ostream tmp(cout.rdbuf());
24
25 TeeDevice logdevice(tmp, ofs);
26 TeeStream logger(logdevice);
27
28 // Set streambuffer for cout
29 cout.rdbuf(logger.rdbuf());
30
31 // Make some logs
32 cout << "Log output to both stdout and file." << endl;
33 }
Compile and test
1 [08:35:24]marcus@goliat:~/tmp/tee$ g++ main.cpp -o main && ./main
2 Log output to both stdout and file.
3
4 [08:56:09]marcus@goliat:~/tmp/tee$ cat stdout.log
5 Log output to both stdout and file.