Re: Something like an ostream...
On 07.09.13 00.54, Jens Thoms Toerring wrote:
I haven't programmed in C++ for some time and now coming back to
it I seem to have my "senior moments". I would like to write a kind
of logger with a twist in that the file name to use for logging will
only be known after a configuration file has been read in. Of course,
I also would like to log problems encountered while reading that con-
figuration file. So my idea was to store the stuff send to the logger
while the file name isn't yet known to a stringstream and, once the
log files name is available, write the accumulated string to that
file and switch to writing to the file for the rest of the time the
program runs.
You can do that, but be aware that the config might be bad and you never
get the log output, not even the problems while loading the config.
We have the same scenario. There are two solutions:
1. either you choose a reasonable fallback when the configured log
target failed to initialize. I.e. you check for a directory where you
have write permissions and store your log there. $cwd, $tmp or whatever.
2. or you refuse to start with a nonzero return code, unless the
configuration is basically OK and the log open succeeded. You use stderr
for fatal error logging so far and switch to the final one as soon as
possible. Since reading the config and opening the log are the first
operations that the application should do I never had the need to buffer
the events before the log is initialized.
Although we implemented both versions I definitely prefer the second
choice. Simply because it is more reliable. It could be difficult in
case of an incident to find the place where the log has gone to. And it
is no good idea to suggest that everything is OK while the configuration
is broken. Doing an abnormal termination is one of the best choices
because it does not hide errors and usually the problem is detected
shortly. And well, if no one cares about the failed start, then the
application is not important anyway.
To come around common problems with bad log configurations we have setup
a global environment var on all servers that contains the basic log
configuration for /all/ applications, basically the target path. This
path is writable lo all local users but not remotely. The application
local configuration only specifies log file names, subdirectories or
other options. And since there are reasonable defaults for the log name
(i.e. the applications executable name) the application config for
logging might be entirely optional. This is some kind of combination of
solution #1 and #2.
You only get problems if several instances of the same application try
to write to the same log. We addressed that by using an atomic appender
that can safely write to the same file from different processes. And of
course, our logger adds some machine readable header information to each
log entry, to identify the source.
I would, of course, like the logger to be an object one can use
the '<<' operator on, so my first idea was to derive it from
std::ostream. But is that still an "is-a" relationship, i.e. a
specialization of std:ostream or is it something that goes be-
yond that?
You already got the hint with streambuf.
Marcel