If you're new with Boost.Log you should read about the library design first, it is quite different from Java. Despite the difference, it is possible to configure the library in a similar way to log4j, and this answer will help to get you started.
Now, to your questions:
- Does that mean that I just have to set the attribute RequestID and than the logger will decide in which file to put the message? How would I do that?
In the particular case of text_multifile_backend
the sink will decide to what file every log record will be written. The set_file_name_composer
call sets a function object that composes the log file name, and as you can see, it involves the RequestID attribute. Naturally, you can use whatever attribute(s) you like, including channels. You should also know that text_multifile_backend
is not the only way (and probably not the most efficient way) to achieve what you want. If the number of different log files is limited, it is typically better to add several text file sinks, one for each file, and set up filtering so that each sink receives its own log records. This approach is described in the answer I linked above.
Regarding adding attributes, there are different ways depending on the use case and the attribute set you want to add it to. In the case of channels, this attribute is automatically provided by the logger, you just create the logger with the channel name and every log record you make through that logger will have it attached as an attribute. The RequestID attribute from the example you pointed to could be added in any possible way. Here are a few common examples:
- It could be added to a logger manually. This is typical, if you create a logger for processing a request (in a broad meaning - whatever 'request' means in your application), and write all log messages related to the request processing through that logger.
- It could be added to a logger as a scoped attribute. This is useful if you don't have a dedicated logger for every request but have a common logger somewhere that is used to write logs related to request processing.
- It could be added as a scoped attribute to thread-specific attributes. This will help if request processing involves multiple loggers in different parts of the program, but at a given point of time only a single thread (the current one) is processing a particular request. Other threads may be processing other requests and set their own thread-specific attributes - they will not interfere.
- Is it even possible with boost to have logging files in different paths?
Of course. As I said, this can be done by adding more than one file sink to the core. By its nature, text_multifile_backend
is already able to write more than one file.
- What will happen if different threads access the same file?
Boost.Log has support for multithreading. On the sinks level, sink frontends implement thread synchronization. For instance, the synchronous_sink
frontend will block contending threads from writing to a single file concurrently. Log records can be written to different sinks concurrently though.
Loggers also have single-threaded and multi-threaded versions, and the latter do additional locking to protect their internal structures from concurrent access. This protection, however, does not extend on sinks (i.e. even if you use an _mt
logger, the sink frontend still has to synchronize threads).
- Will this code in init_logging() effect the application-wide behaviour of the boost logging library? Is this done by some kind of ... global variables?
There are a number of singletons in Boost.Log, yes. Most notably, the logging core, in which you register all sinks and global and thread-specific attributes. Adding a new sink will have effect on the whole application as records from all loggers will start going to that sink (this is why you should generally configure the sink before adding it to the core). Loggers themselves are not related to sinks and in which sink the log records end up is defined solely by filters. But as I mentioned, it is possible to associate loggers and sinks with help of attributes and filters and manage them in a related manner. You will have to write a wrapper class that provides the interface you described and along with Boost.Log logger creates and configures the corresponding sink.