<p>I've been wondering, what is the point of clog? As near as I can tell, clog is the same as cerr but with buffering so it is more efficient. Usually stderr is the same as stdout, so clog is the same as cout. This seems pretty lame to me, so I figure I must be misunderstanding it. If I have log messages going out to the same place I have error messages going out to (perhaps something in /var/log/messages), then I probably am not writing too much out (so there isn't much lost by using non-buffered cerr). In my experience, I want my log messages up to date (not buffered) so I can help find a crash (so I don't want to be using the buffered clog). Apparently I should always be using cerr.</p>

<p>I'd like to be able to redirect clog inside my program. It would be useful to redirect cerr so that when I call a library routine I can control where cerr and clog go to. Can some compilers support this? I just checked DJGPP and stdout is defined as the address of a FILE struct, so it is illegal to do something like "stdout = freopen(...)".</p>

<ul>
<li>Is it possible to redirect clog, cerr, cout, stdin, stdout, and/or stderr?</li>
<li>Is the only difference between clog and cerr the buffering?</li>
<li>How should I implement (or find) a more robust logging facility (links please)?</li>
</ul>

[{'answer_id': 52365, 'author': 'Konrad Rudolph', 'author_id': 1968, 'author_profile': 'https://Stackoverflow.com/users/1968', 'pm_score': 6, 'selected': True, 'text': '<blockquote>\n  <p>Is it possible to redirect clog, cerr, cout, stdin, stdout, and/or stderr?</p>\n</blockquote>\n\n<p>Yes. You want the <a href="http://www.cplusplus.com/reference/iostream/ios/rdbuf.html" rel="noreferrer"><code>rdbuf</code></a> function.</p>\n\n<pre><code>ofstream ofs("logfile");\ncout.rdbuf(ofs.rdbuf());\ncout &lt;&lt; "Goes to file." &lt;&lt; endl;\n</code></pre>\n\n<blockquote>\n  <p>Is the only difference between clog and cerr the buffering?</p>\n</blockquote>\n\n<p>As far as I know, yes.</p>\n'}, {'answer_id': 52381, 'author': 'Ben Collins', 'author_id': 3279, 'author_profile': 'https://Stackoverflow.com/users/3279', 'pm_score': 4, 'selected': False, 'text': '<p>If you\'re in a posix shell environment (I\'m really thinking of bash), you can redirect any \nfile descriptor to any other file descriptor, so to redirect, you can just:</p>\n\n<pre><code>$ myprogram 2&gt;&amp;5 \n</code></pre>\n\n<p>to redirect stderr to the file represented by fd=5.</p>\n\n<p>Edit: on second thought, I like @Konrad Rudolph\'s answer about redirection better.  rdbuf() is a more coherent and portable way to do it.</p>\n\n<p>As for logging, well...I start with the Boost library for all things C++ that isn\'t in the std library.  Behold: <a href="http://www.torjo.com/log2/index.html" rel="nofollow noreferrer">Boost Logging v2</a></p>\n\n<p><strong>Edit</strong>: Boost Logging is <em>not</em> part of the Boost Libraries; it has been reviewed, but not accepted.</p>\n\n<p><strong>Edit</strong>: 2 years later, back in May 2010, Boost did accept a logging library, now called <a href="http://boost-log.sourceforge.net/libs/log/doc/html/index.html" rel="nofollow noreferrer">Boost.Log</a>.</p>\n\n<p>Of course, there are alternatives:</p>\n\n<ul>\n<li><a href="http://log4cpp.sourceforge.net/" rel="nofollow noreferrer">Log4Cpp</a> (a log4j-style API for C++)</li>\n<li><a href="http://logging.apache.org/log4cxx/index.html" rel="nofollow noreferrer">Log4Cxx</a> (Apache-sponsored log4j-style API)</li>\n<li><a href="http://pantheios.sourceforge.net/" rel="nofollow noreferrer">Pantheios</a> (defunct?  last time I tried I couldn\'t get it to build on a recent compiler)</li>\n<li><a href="https://github.com/google/glog" rel="nofollow noreferrer">Google\'s GLog</a> (hat-tip @SuperElectric)</li>\n</ul>\n\n<p>There\'s also the Windows Event logger.</p>\n\n<p>And a couple of articles that may be of use:</p>\n\n<ul>\n<li><a href="http://www.ddj.com/cpp/201804215" rel="nofollow noreferrer">Logging in C++ (Dr. Dobbs)</a></li>\n<li><a href="http://developers.sun.com/solaris/articles/logging.html" rel="nofollow noreferrer">Logging and Tracing Simplified (Sun)</a></li>\n</ul>\n'}, {'answer_id': 4476129, 'author': 'unixman83', 'author_id': 504239, 'author_profile': 'https://Stackoverflow.com/users/504239', 'pm_score': 1, 'selected': False, 'text': '<h2>Basic Logger</h2>\n\n<pre><code>#define myerr(e) {CriticalSectionLocker crit; std::cerr &lt;&lt; e &lt;&lt; std::endl;}\n</code></pre>\n\n<p>Used as <code>myerr("ERR: " &lt;&lt; message);</code> or <code>myerr("WARN: " &lt;&lt; message &lt;&lt; code &lt;&lt; etc);</code></p>\n\n<p>Is very effective.</p>\n\n<p>Then do:</p>\n\n<pre><code>./programname.exe 2&gt; ./stderr.log\nperl parsestderr.pl stderr.log\n</code></pre>\n\n<p><strong>or just parse stderr.log by hand</strong></p>\n\n<p>I admit this is not for <em>extremely</em> performance critical code. But who writes that anyway.</p>\n'}, {'answer_id': 56308274, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>Since there are several answers here about redirection, I will add <a href="http://wordaligned.org/articles/cpp-streambufs" rel="noreferrer">this nice gem</a> I stumbled across recently about redirection:</p>\n\n<pre><code>#include &lt;fstream&gt;\n#include &lt;iostream&gt;\n\nclass redirecter\n{\npublic:\n    redirecter(std::ostream &amp; dst, std::ostream &amp; src)\n        : src(src), sbuf(src.rdbuf(dst.rdbuf())) {}\n    ~redirecter() { src.rdbuf(sbuf); }\nprivate:\n    std::ostream &amp; src;\n    std::streambuf * const sbuf;\n};\n\nvoid hello_world()\n{\n    std::cout &lt;&lt; "Hello, world!\\n";\n}\n\nint main()\n{\n    std::ofstream log("hello-world.log");\n    redirecter redirect(log, std::cout);\n    hello_world();\n    return 0;\n}\n</code></pre>\n\n<p>It\'s basically a redirection class that allows you to redirect any two streams, and restore it when you\'re finished.</p>\n'}, {'answer_id': 57314550, 'author': 'Alexis Wilke', 'author_id': 212378, 'author_profile': 'https://Stackoverflow.com/users/212378', 'pm_score': 2, 'selected': False, 'text': '<h2>Redirections</h2>\n<p>Konrad Rudolph answer is good in regard to how to redirect the <code>std::clog</code> (<code>std::wclog</code>).</p>\n<p>Other answers tell you about various possibilities such as using a command line redirect such as <code>2&gt;output.log</code>. With Unix you can also create a file and add another output to your commands with something like <code>3&gt;output.log</code>. In your program you then have to use <code>fd</code> number 3 to print the logs. You can continue to print to <code>stdout</code> and <code>stderr</code> normally. The Visual Studio IDE has a similar feature with their <code>CDebug</code> command, which sends its output to the IDE output window.</p>\n<blockquote>\n<p><code>stderr</code> is the same as <code>stdout</code>?</p>\n</blockquote>\n<p>This is generally true, but under Unix you can setup the <code>stderr</code> to <code>/dev/console</code> which means that it goes to another <code>tty</code> (a.k.a. terminal). It\'s rarely used these days. I had it that way on IRIX. I would open a separate X-Window and see errors in it.</p>\n<p>Also many people send error messages to <code>/dev/null</code>. On the command line you write:</p>\n<pre><code>command ...args... 2&gt;/dev/null\n</code></pre>\n<h2>syslog</h2>\n<p>One thing not mentioned, under Unix, you also have <code>syslog()</code>.</p>\n<p>The newest versions under Linux (and probably Mac OS/X) does a lot more than it used to. Especially, it can use the identity and some other parameters to redirect the logs to a specific file (i.e. <code>mail.log</code>). The syslog mechanism can be used between computers, so logs from computer A can be sent to computer B. And of course you can filter logs in various ways, especially by severity.</p>\n<p>The <code>syslog()</code> is also very simple to use:</p>\n<pre><code>syslog(LOG_ERR, &quot;message #%d&quot;, count++);\n</code></pre>\n<p>It offers 8 levels (or severity), a format a la <code>printf()</code>, and a list of arguments for the format.</p>\n<p>Programmatically, you may tweak a few things if you first call the <code>openlog()</code> function. You must call it before your first call to <code>syslog()</code>.</p>\n<p>As mentioned by unixman83, you may want to use a macro instead. That way you can include some parameters to your messages without having to repeat them over and over again. Maybe something like this (see <a href="https://en.wikipedia.org/wiki/Variadic_macro" rel="nofollow noreferrer">Variadic Macro</a>):</p>\n<pre><code>// (not tested... requires msg to be a string literal)\n#define LOG(lvl, msg, ...) \\\n     syslog(lvl, msg &quot; (in &quot; __FILE__ &quot;:%d)&quot;, __VA_ARGS__, __LINE__)\n</code></pre>\n<p>You may also find <code>__func__</code> useful.</p>\n<p>The redirection, filtering, etc. is done by creating configuration files. Here is <a href="https://github.com/m2osw/snapwebsites/blob/master/snapbounce/conf/02-mail.conf" rel="nofollow noreferrer">an example</a> from my snapwebsites project:</p>\n<pre><code>mail.err /var/log/mail/mail.err\nmail.* /var/log/mail/mail.log\n&amp; stop\n</code></pre>\n<p>I install the file under <code>/etc/rsyslog.d/</code> and run:</p>\n<pre><code>invoke-rc.d rsyslog restart\n</code></pre>\n<p>so the <code>syslog</code> server handles that change and saves any mail related logs to those folders.</p>\n<p><em>Note: I also have to create the <code>/var/log/mail</code> folder and the files inside the folder to make sure it all works right (because otherwise the mail daemon may not have enough permissions.)</em></p>\n<h2>snaplogger (a little plug)</h2>\n<p>I\'ve used <a href="https://github.com/log4cplus/log4cplus" rel="nofollow noreferrer">log4cplus</a>, which, since version 1.2.x, is quite good. I have three cons about it, though:</p>\n<ol>\n<li>it requires me to completely clear everything if I want to call <code>fork();</code> somehow it does not survive a <code>fork();</code> call properly... (at least in the version I had it used a thread)</li>\n<li>the configuration files (<code>.properties</code>) are not easy to manage in my environment where I like the administrators to make changes without modifying the original</li>\n<li>it uses C++03 and we are now in 2019... I\'d like to have at least C++11</li>\n</ol>\n<p>Because of that, and especially because of point (1), I wrote my own version called <a href="https://github.com/m2osw/snaplogger" rel="nofollow noreferrer">snaplogger</a>. This is not exactly a standalone project, though. I use many other projects from the snapcpp environment (it\'s much easier to just get snapcpp and run the <code>bin/build-snap</code> script or just <a href="https://launchpad.net/%7Esnapcpp/+archive/ubuntu/ppa" rel="nofollow noreferrer">get the binaries from launchpad</a>.)</p>\n<p>The advantage of using a logger such as snaplogger or log4cplus is that you generally can define any number of destinations and many other parameters (such as the severity level as offered by <code>syslog()</code>). The log4cplus is capable of sending its output to many different places: files, syslog, MS-Windows log system, console, a server, etc. Check out the appenders in those two projects to have an idea of the list of possibilities. The interesting factor here is that any log can be sent to all the destinations. This is useful to have a file named all.log where all your services send their logs. This allows to understand certain bugs which would not be as easy with separate log files when running many services in parallel.</p>\n<p>Here is a simple example in a snaplogger configuration file:</p>\n<pre><code>[all]\ntype=file\nlock=true\nfilename=/var/log/snapwebsites/all.log\n\n[file]\nlock=false\nfilename=/var/log/snapwebsites/firewall.log\n</code></pre>\n<p>Notice that for the <code>all.log</code> file I require a lock so multiple writers do not mangle the logs between each others. It\'s not necessary for the <code>[file]</code> section because I only have one process (no threads) for that one.</p>\n<p>Both offer you a way to add your own appenders. So for example if you have a Qt application with an output window, you could write an appender to send the output of the <code>SNAP_LOG_ERROR()</code> calls to that window.</p>\n<p><code>snaplogger</code> also offers you a way to extend the variable support in messages (also called the format.) For example, I can insert the date using the <code>${date}</code> variable. Then I can tweak it with a parameter. To only output the year, I use <code>${date:year}</code>. This variable parameter support is also extensible.</p>\n<p><code>snaplogger</code> can filter the output by severity (like syslog), by a regex, and by <em>component</em>. We have a <code>normal</code> and a <code>secure</code> component, the default is <code>normal</code>. I want logs sent to the <code>secure</code> component to be written to secure files. This means in a sub-directory which is way more protected than the normal logs that most admins can review. When I run my HTTP services, some times I send information such as the last 3 digits of a credit card. I prefer to have those in a secure log. It could also be password related errors. Anything I deem to be a security risk in a log, really. Again, components are extensible so you can have your own.</p>\n'}, {'answer_id': 62689338, 'author': 'Apteryx', 'author_id': 7420896, 'author_profile': 'https://Stackoverflow.com/users/7420896', 'pm_score': 2, 'selected': False, 'text': "<p>One little point about the redirecter class. It needs to be destroyed properly, and only once. The destructor will ensure this will happen if the function it is declared in actually returns, and the object itself is never copied.</p>\n<p>To ensure it can't be copied, provide private copy and assignment operators:</p>\n<pre><code>class redirecter\n{\npublic:\n    redirecter(std::ostream &amp; src, std::ostream &amp; dst)\n        : src_(src), sbuf(src.rdbuf(dst.rdbuf())) {}\n    ~redirecter() { src.rdbuf(sbuf); }\nprivate:\n    std::ostream &amp; src_;\n    std::streambuf * const sbuf_;\n    // Prevent copying.                        \n    redirecter( const redirecter&amp; );\n    redirecter&amp; operator=( const redirecter&amp; );\n};\n</code></pre>\n<p>I'm using this technique by redirecting std::clog to a log file in my main(). To ensure that main() actually returns, I place the guts of main() in a try/catch block. Then elsewhere in my program, where I might call exit(), I throw an exception instead. This returns control to main() which can then execute a return statement.</p>\n"}]
['https://Stackoverflow.com/questions/52357', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4662/']