I work on Unix on a C++ program that send messages to syslog.
The current code uses the syslog system call that works like printf.
Now I would prefer to use a stream for that purpose instead, typically the built-in std::clog. But clog merely redirect output to stderr, not to syslog and that is useless for me as I also use stderr and stdout for other purposes.
I've seen in another answer that it's quite easy to redirect it to a file using rdbuf() but I see no way to apply that method to call syslog as openlog does not return a file handler I could use to tie a stream on it.
Is there another method to do that ? (looks pretty basic for unix programming) ?
Edit: I'm looking for a solution that does not use external library. What @Chris is proposing could be a good start but is still a bit vague to become the accepted answer.
Edit: using Boost.IOStreams is OK as my project already use Boost anyway.
Linking with external library is possible but is also a concern as it's GPL code. Dependencies are also a burden as they may conflict with other components, not be available on my Linux distribution, introduce third-party bugs, etc. If this is the only solution I may consider completely avoiding streams... (a pity).
I needed something simple like this too, so I just put this together:
log.h:
log.cc:
In
main()
I initialize clog:Then whenever I want to log, it's easy:
I designed a OStreamedLog class very similar to what was shown above, except my OStreamedLog objects are set up to use an arbitrary ostringstream object, like @Basilevs suggested.
First, there is the class definition of Log, very similar to what @eater and @Chris Kaminski mentioned above. Then, my OStreamedLog class definition, which contains a Log object:
Now, when you need to log, just call:
Of course, you could collapse the whole Log definition into your OStreamedLog class, but you might want to do other things in your base Log object and use wrappers like above to differentiate the different types of logs. For example you could have human-readable diagnostic logs (sent as ASCII text), binary logs (for processing later) or a TLS-streaming log (to a northbound server, for example).
You could define an streambuf that calls syslog. For example:
then you would simply write the following to redirect clog:
There are a few more functions you would probably have to override, here's a good reference to the streambuf api.
Another version in part inspired by eater. It doesn't redirect std::clog per se, but uses familiar stream syntax.
To use it, you can do something like: