
Please explicitly state in your review whether the library should be accepted.
Yes, I think the library should be accepted. In my view, the library should not be reviewed with the objective of whether it contains all possible implementations that might desired in the world, but whether it’s design and implementation is flexible enough to adopt useful extensions, like binary logging or a printf-style interface. It is unreal to expect from a first implementation to be the mother of all logging libraries, i.e. contain all desired functionality at once. It should be judged on whether it can BECOME the mother of all logging libraries and in my opinion it is flexible enough to do so. In our project, described in last month's ACCU Overload 95 (http://accu.org/index.php/journals/1606), we required a powerful logging/tracing library, mainly for the higher levels of the application. Since our guideline is to use Boost functionality wherever suitable, we particularly looked at the Boost library to fill our needs. It seemed to fulfil our requirements quite well, so we decided to take it on-board. We integrated it into our software, and first experience is that it works quite well. However, in the light of this review I would pay attention to a few aspects that I came across: - complexity of the interface, and how to improve - few design/implementation aspects - high-performance requirements INTERFACE COMPLEXITY ===================== A number of reviewers have mentioned the complexity of the interface and the fact that this might discourage new users. I think introduction of trivial logging partly reduced this problem, but whenever you want to use the library in a more subtle way, you have to know a lot and you have to do a lot. When implementing the various sinks and backend flavours I too found my code blurred with heavy template and shared-pointer handling at a level where I didn't want to see it. Thinking about how to improve this, it seemed to me that the library was lacking an extra interface level between trivial logging and the low-level interface of sinks etc. This extra interface should hide complexity, but still allow the user full control over the detailed aspects of the logging components. In my view this extra-level interface could be well-solved with a policy-based design. The user should just be required to provide the policies for the various aspects (front-end, back-end, formatter, filters) as well as the necessary parameters (file name etc.). The actual assembly of the logging components should be done by the library internally. I put this idea into practice, and, although not an expert in this field, developed a few policy-based creator classes, as well as the most common policies that I could forsee. This made the library much easier to manage and my code look much better. Adopting this approach would greatly remove the objections against the highly complicated interface. Users can just use the policies provided, and if the ones provided do not fit a user's needs, he can easily copy an existing one and modify it according to his wishes. The current design of the library allows insertion of this extra interface level well, proving its flexibility. DESIGN/IMPLEMENTATION ASPECTS =============================== When using the library I came across a few design aspects that might need some improvement. 1. Missing some polymorphism I know it is cursing in the church, but at certain moments I could do with a bit smarter use of polymorphism. To give an example, when my application shuts down unexpectedly, I want to tell the sinks around to stop their work and dump their contents if necessary. For the moment, and as far as i know, I still have to make a distinction between synchronous and asynchronous sinks, as only the asynchronous sinks support these stop methods, and even then I have to take the particular kind of backend in consideration in order to approach them, as this stop method is attached to the backend-templated class. It would be better to lift these methods to a class higher in the hierarchy. There are a few other points in the design were this is the case as well. This being said, there might be good reasons for the current design that I cannot oversee, but then I’d like to see them mentioned in the documentation. 2. In some cases, you might want to be more in control of what the logging library is actually doing. When sending off messages to a sync or async sink, you are only partially in control. Therefor my idea would be to provide something like a buffering logger, that buffers the messages it receives, and only sends it off to the core when the user tells him to. HIGH-PERFORMANCE REQUIREMENTS ================================ In my view, one of the most important aspects to judge a logging library on is its performance. I haven't seen to much about it in the reviews, but I think it is one of the first thing to look at when comparing libraries. I haven't performed comparison tests in detail, but from the results published it looks like Boost.Log is still lagging a bit behind in the multi-threaded case. The question is whether there is room for improvement here. If not, you will definitely loose out on faster libraries. When looking at our current project, there are certain parts of the application where we need a real fast (i.e. low cost) logging facility, and that is something that the current library is not going to offer (nor any of the more common logging libraries around; too often I read comments like "we choose rlog because it is twice as fast as.. "). So my idea would be to develop a lightweight logging module, that can operate next to the current functionality, but is particularly suited for applications or parts of applications where high performance is an issue. This could also be the light and simple library that people are asking for. I think it would be great to have both under one hood, allowing the user to select the kind of performance vs. capability that he wants. This also takes away the burden on the current implementation of having to be both lightweight and feature-rich. For the rest of the formal review questions:
What is your evaluation of the design? The design covers a good set of requirements to start with. It seems to be quite flexible to cater for new functionality. As stated, it might be useful to ease the use of the highly templated interface to prevent it of becoming a hurdle for novices.
What is your evaluation of the implementation? Only looked partly to the implementation, especially with performance in mind. I'm convinced that the implementation is good in general, although improvements can be made, especially with performance in mind. Date/time formatting is still a candidate in this case.
What is your evaluation of the documentation? The level of documentation is sufficient but not more then that. It seems to be written from the view of the developer or from a highly-experienced user. It therefor makes it difficult for a novice to use the library quickly. The introduction of trivial logging however improved this situation. In my view it should be reworked somewhat to cover the questions of less knowledgeable users (i.e. more explanation, more illustration through examples or references to the examples in the code).
What is your evaluation of the potential usefulness of this library? I think the library is very usefull. Regarding covered functionality it is somewhat equal to other well-known logging libraries, and the design is well-suited for extension in all areas where more functionality is required.
Did you try to use the library? With what compiler? Did you have any problems? We tried the library with Microsoft Visual C++ 8.0. We didn’t find any problems with the compiler, apart from some issue with MFC. There is a problem linking Boost.Thread statically with MFC, but this is a problem that resides outside Boost.Log.
Are you knowledgeable about the problem domain? Yes, developed this kind of functionality in earlier days.
-- View this message in context: http://old.nabble.com/-log--Boost.Log-formal-review-tp27940788p27940788.html Sent from the Boost - Dev mailing list archive at Nabble.com.

On 03/18/2010 01:57 PM, M-Square wrote:
INTERFACE COMPLEXITY =====================
When implementing the various sinks and backend flavours I too found my code blurred with heavy template and shared-pointer handling at a level where I didn't want to see it. Thinking about how to improve this, it seemed to me that the library was lacking an extra interface level between trivial logging and the low-level interface of sinks etc. This extra interface should hide complexity, but still allow the user full control over the detailed aspects of the logging components.
In my view this extra-level interface could be well-solved with a policy-based design. The user should just be required to provide the policies for the various aspects (front-end, back-end, formatter, filters) as well as the necessary parameters (file name etc.). The actual assembly of the logging components should be done by the library internally.
I put this idea into practice, and, although not an expert in this field, developed a few policy-based creator classes, as well as the most common policies that I could forsee. This made the library much easier to manage and my code look much better.
Adopting this approach would greatly remove the objections against the highly complicated interface. Users can just use the policies provided, and if the ones provided do not fit a user's needs, he can easily copy an existing one and modify it according to his wishes. The current design of the library allows insertion of this extra interface level well, proving its flexibility.
Thanks, this looks like an interesting idea. This made me thinking about changing the sinks design in order to make it less verbose to initialize on one hand and more extensible on the other. The idea is to present the sink as a pipeline of consumers, which would include the current frontend, backend and probably other things. Something like this comes to mind: typedef sink_pipeline< synchronous, formatter, text_file
sink_t;
shared_ptr< sink_t > s = new sink_t( file_name = "file_%N.log", rotation_size = 1024 * 1024, ... ); I think, it would also make it possible to connect several backends with a single frontend and/or a common formatter, which was requested during the review.
DESIGN/IMPLEMENTATION ASPECTS ===============================
When using the library I came across a few design aspects that might need some improvement.
1. Missing some polymorphism
I know it is cursing in the church, but at certain moments I could do with a bit smarter use of polymorphism. To give an example, when my application shuts down unexpectedly, I want to tell the sinks around to stop their work and dump their contents if necessary. For the moment, and as far as i know, I still have to make a distinction between synchronous and asynchronous sinks, as only the asynchronous sinks support these stop methods, and even then I have to take the particular kind of backend in consideration in order to approach them, as this stop method is attached to the backend-templated class. It would be better to lift these methods to a class higher in the hierarchy.
Hmm, a reasonable suggestion. I think, a flushing method could be added to the basic sink interface. However, I'm not sure about the stopping method, since it only makes sense for asynchronous sinks.
2. In some cases, you might want to be more in control of what the logging library is actually doing. When sending off messages to a sync or async sink, you are only partially in control. Therefor my idea would be to provide something like a buffering logger, that buffers the messages it receives, and only sends it off to the core when the user tells him to.
I think, this should be doable by implementing a logger feature.
HIGH-PERFORMANCE REQUIREMENTS ================================
I haven't performed comparison tests in detail, but from the results published it looks like Boost.Log is still lagging a bit behind in the multi-threaded case.
AFAICT, the results show the opposite. According to the tests, Boost.Log scales slightly better than log4cxx.

Andrey Semashev wrote:
I think, it would also make it possible to connect several backends with a single frontend and/or a common formatter, which was requested during the review. Yeah, that would be really cool :-) . Currently I am using the logging functionality provided by the Poco library (http://www.pocoproject.org). They have a chaining mechanism. This also includes splitters which distribute log records to several sub-chains.
In "my" scenario, I have a central filter (to block all trace messages, for instance), a single formatter, a splitter and then the backends (with their own filters). Regards, Roland PS: I did not even read half of all the mails of this review, but from what I saw, Boost.Log is going to make quite a leap if you follow up all the suggestions and discussions. I am very much looking forward to migrating as soon as the next version is available. Thanks for all the time and efforts you invest in this project!
participants (3)
-
Andrey Semashev
-
M-Square
-
Roland Bock