
Vladimir Batov wrote:
... You can either create a logger and use it as an independent object, or you can declare a global logger and use it everywhere you need it. The first approach is good to store loggers as class members. The second is convenient if you tend to use functional code or don't need any context-specific attributes in it. It can be done like this:
BOOST_LOG_DECLARE_GLOBAL_LOGGER(my_logger, src::severity_logger_mt< >)
void foo() { src::severity_logger_mt< >& lg = my_logger::get(); // go ahead logging }
Hmm, I honestly think that having "loggers as class members" is a bad idea.
And I find it extremely useful. In fact, I tend to avoid making loggers irrelevant to some sensible entity in the program. For example, if I have a class that implements a network connection, I would most likely make logger a member of this class. This allows to seemlessly embed information related to this connection into log records. In consequence, this allows to apply filtering based on this information.
I do not usually like global objects either (static initialization issues, too much visibility). However, what I definitely use a lot is retrieving the same log by name in different compilation modules (that takes the visibility down). Like
boost::log log1(name); boost::log log2(name); // The same as log1
The example above does just that. All you need is to have the BOOST_LOG_DECLARE_GLOBAL_LOGGER in some common header, and include it whenever you need the my_logger logger. The my_logger is a singleton that is accessible from different translation units and even different modules (dlls, sos). It does have static initialization problems solved. This is the key difference from declaring a namespace-scope logger variable.