Boost logo

Boost :

From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2008-08-20 12:27:39


Boris wrote:
> I've been converting a program from John's logging library to Andrey's
> logging library. I have to continue playing around with Andrey's library
> but in the moment I prefer it over John's library. I can't say really
> that this or that is better - it's more the overall handling of Andrey's
> logging library which feels more natural for me. Maybe it's also
> Andrey's documentation which is rather good (the definitions and design
> overview really help to understand the big picture before you dive into
> all the details).
>
> I've some questions though for Andrey:
>
> * Where is the connection between a source and a sink? In the
> basic_usage example there are two sinks registered (console and file).
> There is then one source created which is used to log a message. The
> message is then sent to both the console and the file. But what if I
> want to use for example two sources and want messages from each source
> to be sent to a different sink? Do I understand correctly that I need to
> use attributes somehow and filter records based on attribute values? I
> guess I would need to add an attribute to each source and set a filter
> in each sink to make sure only messages with a certain attribute are
> written?

Correct. There is no direct connection between sources and sinks, so
that records from any source may go to any sink. Which sink will finally
process a record is totally defined by filtering.

If you want to relate your loggers and sinks, the simpliest way to do so
is to use channel_logger and set up filters in your sinks that will pass
through only records from needed channels.

> * If I want to format a message and add a timestamp why do I need to
> write boost::log::formatters::date_time("TimeStamp") and can't write
> boost::log::formatters::attr("TimeStamp")? Doesn't the attribute value
> know how to be serialized (or isn't it written to a std::ostream)?

The attr formatter should work too. The date_time formatter provides
additional formatting facilities, while attr always simply puts the
attribute value to a stream.

> If I
> use boost::log::formatters::attr("TimeStamp") nothing is written to the
> log file.

That's odd. Could you send a short code sample that shows the problem?

> * I've been reading
> http://boost-log.sourceforge.net/libs/log/doc/html/advanced/advanced.html#advanced.advanced.sources.global_storage
> a few times but still don't understand why I can't (or shouldn't)
> instantiate a global logger with "boost::log::sources::logger logger;".
> I actually did this and everything works (or at least seems to work :).
> Must the macro BOOST_LOG_DECLARE_GLOBAL_LOGGER really be used when a
> global logger is created? Maybe I better understand if I ask
> differently: What is so special about a logger that I need to use a
> macro to define it globally while I can create for example a global
> std::string instance without a macro?

There's nothing in loggers that prevent you from creating them globally.
There are several significant differences, though, between using the
macro and a global logger:
1. In general, having global non-POD variables (not necessarily a
logger) is not thread-safe. If there are multiple threads running while
global variables are initialized, you may end up executing one object's
constructor multiple times concurrently. The macro is thread safe in
this respect.
2. The macro defines a logger that will be truly global throughout the
application, even if the application consists of multiple modules. By
doing so, it doesn't introduce any additional linking dependences.
Global variables, depending on their definition, are visible either in a
single translation unit, or a single module. You will notice the
difference when you try to manage attributes of the global logger.
3. The loggers defined with the macro are lazily constructed, while
global variables tend to be constructed on the application startup.

As a side effect of the macro implementation, it is significantly easier
to use the macro to declare loggers in header-only components. In order
to achieve this with global variables you would have to resort to
various tricks to avoid linking failures.

> * By default there is a newline appended to every message written?

Yes, the text ostream sink adds a newline after each log record.

> By the way, looking at the TODO list: I would be very much interested in
> Windows NT event log support. I'm sure it would also convince more
> developers to use a logging library as writing texts to files in some
> fancy ways can also be done without a logging library. :)

That's why it's in TODO. :) However, I'm not sure this functionality is
a must for the first release.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk