Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

How to use Boost.Log in libraries?
PrevUpHomeNext

When using Boost.Log with libraries, there are several recommendadions to follow. First, as noted in the library configuration section, using the library in multiple modules (including libraries and the application itself) requires Boost.Log to be built as a shared library. This is needed because Boost.Log maintains a number of process-wide singletons and may not function correctly if these singletons are duplicated. If building Boost.Log as a shared library is not desirable, it is possible to encapsulate it in a single user's shared library and link the rest of the modules with that library. In this case, Boost.Log can be built as a shared library and linked into user's shared library. The shared library API and other modules must not use Boost.Log components, including:

  • Logging core
  • Sinks
  • Loggers
  • Attributes, including named scope markup
  • Library configuration helpers, including filter, formatter and settings parsers

However, user's shared library may provide its own API that will implement similar functionality, using relevant Boost.Log facilities internally.

Next, it is important to ensure that logging configuration is coordinated between all modules. For example, if a file log is needed, only one file sink must be added, regardless of how many libraries are using logging. The preferred way to achieve this is perform logging configuration only in the main application, for the following reasons:

  • Logging configuration should be performed early in the main function, which is implemented in the application. Using global constructors in libraries can be problematic due to undefined order of global initialization and the possibility of dynamic loading and unloading of the libraries.
  • Libraries are normally "serving the needs" of the main application, and conceptually it is the application that must decide how the library exposes its diagnostic information such as logs. One application may want to output its logs to console, another one store it in a file, and a third one may want to completely suppress any logging. A well-behaving library should transparently support any such use case and Boost.Log allows to achieve exactly that.

It should be noted that having logging configured by the application implies that the application is written in C++ and can use Boost.Log. If this is not the case, libraries should still allow for this design and offer an API for configuring logging on behalf of the application. Alternatively, a separate library written in C++ can be used for the sole purpose of configuring logging. This way logging set up decisions are still made by the application, indirectly through the library API.

To implement this design, here are recommendations for library writers:

  • Libraries should refrain from adding or configuring sinks, filters or formatters, including using library configuration helpers. The exception is the aforementioned API that configures logging on behalf of the application, but this configuretion should not be performed by default.
  • Libraries should be careful about adding or removing global and thread-specific attributes in the logging core - any such actions must be clearly documented.
  • Libraries can freely create loggers, modify their attributes and emit log records.
  • Libraries may use named scope markup, even if they don't register named_scope attribute themselves. The application can add and configure this attribute, which will enable this information in the output.
  • Libraries should document the attributes it uses, incliding their names and value types, so that the application can configure filters and formatters accordingly. This includes the message text attribute - in particular, it is important to know the type of the attribute value (e.g. std::string vs. std::wstring) and what character encoding it uses. If possible, declare attribute keywords for all attributes used by the library in a public header.
  • Libraries are recommended to mark all log records they emit with an attribute. For example, all log records could be made in a specific channel. This way the application will be able to configure logging specifically for the library (for example, extract log records from the library to a separate file or apply a different severity level threshold).

PrevUpHomeNext