[log] How to set/reset a channel-specific filter

Hi We're currently reviewing Boost.Log and are wondering what is the best way to implement channel-specific filters. More precisiely, we are currently using the following "objects": - 2 sinks (one to debug output window, one to file) - several severity_channel_logger_mt objects, all declared with BOOST_LOG_DECLARE_GLOBAL_LOGGER, each of these is guaranteed to have a unique channel name For each of the channels, we would like to set a filter that only applies to records logged through the given channel. Since we can't seem to set a filter on the logger itself, we're wondering what is the best way to accomplish this? It seems as though both the core as well as the sinks only accept one filter. So, it seems we would have to a) assemble a filter expression that includes all the channels we'd like to filter on. *Or*, we could b) add exactly two sinks per logger object and set the desired filter on both sinks. Of course, we'd still want to only log to one file, so the question arises whether it is safe to have multiple sinks write to one file. If we go with method a), we'd need a way to enumerate all global loggers. If we go with b), we'd need a method to enumerate all the sinks in the system. We have not found a way to accomplish any of these tasks, how do we do this? Thanks & Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

On 03/16/2010 02:26 PM, Andreas Huber wrote:
Hi
We're currently reviewing Boost.Log and are wondering what is the best way to implement channel-specific filters. More precisiely, we are currently using the following "objects":
- 2 sinks (one to debug output window, one to file) - several severity_channel_logger_mt objects, all declared with BOOST_LOG_DECLARE_GLOBAL_LOGGER, each of these is guaranteed to have a unique channel name
For each of the channels, we would like to set a filter that only applies to records logged through the given channel. Since we can't seem to set a filter on the logger itself, we're wondering what is the best way to accomplish this?
It seems as though both the core as well as the sinks only accept one filter. So, it seems we would have to a) assemble a filter expression that includes all the channels we'd like to filter on. *Or*, we could b) add exactly two sinks per logger object and set the desired filter on both sinks. Of course, we'd still want to only log to one file, so the question arises whether it is safe to have multiple sinks write to one file.
No, two sinks should not access the same file.
If we go with method a), we'd need a way to enumerate all global loggers.
Not sure why would you need to enumerate loggers. You could simply specify all the channels in the filter, if their number is not very big. If it is, you can create your own function that accepts the channel name and then decides if it is enabled. This function can then be converted into a filter like this: bool is_channel_enabled(std::string const& chan_name); sink->set_filter( flt::attr< std::string >("Channel").satisfies(&is_channel_enabled) );

"Andrey Semashev" <andrey.semashev@gmail.com> wrote in message news:4B9FAFD5.50409@gmail.com...
If we go with method a), we'd need a way to enumerate all global loggers.
Not sure why would you need to enumerate loggers. You could simply specify all the channels in the filter, if their number is not very big.
Loggers are declared by thrird party code, so we have no idea about the number of loggers.
If it is, you can create your own function that accepts the channel name and then decides if it is enabled. This function can then be converted into a filter like this:
bool is_channel_enabled(std::string const& chan_name);
sink->set_filter( flt::attr< std::string >("Channel").satisfies(&is_channel_enabled) );
Ok, that will certainly work for us, but I'd consider this a (small) hack, because we'd have to duplicate information that is presumably already present in Boost.Log. More precisely, we want to provide a utility function where you pass in a logger and a severity and the function then modifies the global filter so that all records comming from the specified logger with a severity below the specified one will be discarded. Unless I'm missing something, this would require us keeping a global list of all loggers that have a filter applied, correct? I assumed that somewhere Boost.Log keeps such a list anyway, so I'd rather use that one than build our own. Thanks & Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

On 03/16/2010 08:22 PM, Andreas Huber wrote:
"Andrey Semashev" <andrey.semashev@gmail.com> wrote in message news:4B9FAFD5.50409@gmail.com...
If we go with method a), we'd need a way to enumerate all global loggers.
Not sure why would you need to enumerate loggers. You could simply specify all the channels in the filter, if their number is not very big.
Loggers are declared by thrird party code, so we have no idea about the number of loggers.
I see.
If it is, you can create your own function that accepts the channel name and then decides if it is enabled. This function can then be converted into a filter like this:
bool is_channel_enabled(std::string const& chan_name);
sink->set_filter( flt::attr< std::string >("Channel").satisfies(&is_channel_enabled) );
Ok, that will certainly work for us, but I'd consider this a (small) hack, because we'd have to duplicate information that is presumably already present in Boost.Log.
The loggers are not related to each other, so if some logger has a channel attribute, the library (the core, filters, etc.) won't know that until it starts emitting log records.
More precisely, we want to provide a utility function where you pass in a logger and a severity and the function then modifies the global filter so that all records comming from the specified logger with a severity below the specified one will be discarded.
But if you can pass a logger to this function, why can't you pass the channel name?
Unless I'm missing something, this would require us keeping a global list of all loggers that have a filter applied, correct?
Unless you can work with channel names instead of loggers, yes.
I assumed that somewhere Boost.Log keeps such a list anyway, so I'd rather use that one than build our own.
No, the library doesn't keep track of loggers.

More precisely, we want to provide a utility function where you pass in a logger and a severity and the function then modifies the global filter so that all records comming from the specified logger with a severity below the specified one will be discarded.
But if you can pass a logger to this function, why can't you pass the channel name?
I guess I can, see below.
Unless I'm missing something, this would require us keeping a global list of all loggers that have a filter applied, correct?
Unless you can work with channel names instead of loggers, yes.
I don't understand, it seems even if I have the channel name (instead of the logger), I still need to maintain a global map that associates each channel name with its minimum severity level, right? Otherwise I don't see how I can implement is_channel_enabled. Anyway, doing this certainly is no big deal. It just seems a bit odd, because it would be easier and more efficient to implement if we could set a filter on a logger. Thanks & Regards, Andreas

On 03/16/2010 11:08 PM, Andreas Huber wrote:
Unless I'm missing something, this would require us keeping a global list of all loggers that have a filter applied, correct?
Unless you can work with channel names instead of loggers, yes.
I don't understand, it seems even if I have the channel name (instead of the logger), I still need to maintain a global map that associates each channel name with its minimum severity level, right? Otherwise I don't see how I can implement is_channel_enabled.
Right, the function will need some kind of container of all enabled channels.
Anyway, doing this certainly is no big deal. It just seems a bit odd, because it would be easier and more efficient to implement if we could set a filter on a logger.
Loggers don't filter records, because you're not restricted to have a single logger per channel. But if that restriction is mandated in your application, you can implement a logger feature that would do additional filtering inside the logger.

Anyway, doing this certainly is no big deal. It just seems a bit odd, because it would be easier and more efficient to implement if we could set a filter on a logger.
Loggers don't filter records, because you're not restricted to have a single logger per channel.
Ok.
But if that restriction is mandated in your application, you can implement a logger feature that would do additional filtering inside the logger.
Ok, I guess this means duplicating most from channel_logger.hpp, right? Thanks, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

On 03/17/2010 12:21 PM, Andreas Huber wrote:
But if that restriction is mandated in your application, you can implement a logger feature that would do additional filtering inside the logger.
Ok, I guess this means duplicating most from channel_logger.hpp, right?
channel_feature.hpp. I hate to say it, but it seems so. I should have offered a method to acquire the channel from the channel_feature.
participants (2)
-
Andreas Huber
-
Andrey Semashev