...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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:
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:
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.
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:
named_scope
attribute themselves. The application can add and configure this attribute,
which will enable this information in the output.
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.