
Vladimir.Batov@wrsa.com.au wrote:
Andrey,
Thank you for your contribution. I do not think I'll be participating in trial-runs or review as such. However, I read through the documentation and looked at the interface and I thought I'll give you my first (well, second, I looked at your lib. before) impression. I realize that everyone probably has something to say about logging and such a debate can get hot. So, I want to say beforehand that my reply is merely my impression (not a review or criticism of any kind).
Thank you for your feedback.
Firstly, it certainly seems very rich in features and configurable. That is certainly a huge plus for such a library as logging. However, I was truly overwhelmed by the documentation, the interface and the deployment examples. I seemed to be reading about familiar concepts -- severity levels, sinks, filters, formatters, streams/channels. However, after all that I did not feel an inch closer to actually deploying your library. I consider myself a moderately intelligent person but the seeming complexity felt quite intimidating. Somehow other implementations I read about (J.Torjo's, log4cpp, log4j, a bunch of loggers at SourceForge) went down much easier.
Roughly, as a user I'd expect something as straightforward as
boost::log log(name); // Create a log boost::log::sink sink = boost::log::sink(file)(stdout)(event_log); // Set up sinks boost::log::formatter fmt = boost::log::formatter(date)(thread_id)(name); // Set up the formatter boost::log channel = log.channel(channel-name); // Create a channel
log(sink)(fmt); // Associate sinks and formatting
if (log) log << "Hello, main world"; if (channel) channel << "Hello, channel world";
Maybe that's what your interface does. I just did not get that warm and fuzzy easiness/familiarity feeling after reading the docs and looking at the deployment examples. I feel there is a considerable room for improvement here.
There are different ways to initialize the library, including reading a settings file and initializing from the code. The latter is quite straightforward and basically resembles what you suggested. However, point taken. I must admit, I didn't pay much attention to examples that could help to grasp the library better.
In particular I was left puzzled how you actually create a log instance (I think in the docs it is boost::src::logger). I'd expect to be able to create a log instance with a name and to be able to retrieve that same instance by the name anywhere in the program. That is,
boost::log log1(name); boost::log log2(name);
would be referring to the same log instance (pointer semantics). That'd be very liberating.
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 }