[Log] How to use a channel that is constant per file?
Hi all, I want to use boost's log library to output messages to the console which feature a per-message severity and a per-file channel. I already tried two approaches, none of which was satisfying: === 1. approach === The class boost::log::sources::severity_channel_logger supports both severity and channel and I could define it in each source file like so: --- 8< --- BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_channel_logger< boost::log::trivial::severity_level, std::string > ) --- >8 --- Unfortunately, using it like this requires me to redundantly add the channel to each log message, which is very inconvenient because it is the same for all logs in the file. --- 8< --- // Message.cpp BOOST_LOG_CHANNEL_SEV(log, Message, trace) << "Hello, world"; --- >8 --- === 2. approach === I defined my logger like this: --- 8< --- BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_logger< boost::log::trivial::severity_level > ) --- >8 --- Then, in each file, I manually set the "Channel" attribute for the logger, like so: --- 8< --- // Message.cpp log::get().add_attribute( "Channel", boost::log::attributes::make_constant("Message")); --- >8 --- This works, but as the "log" object seems to be stored globally, I would have to "invent" new names for the logger object in each file. This is both insecure and prevents the usage of macros (I think). So here's the question: What would be the recommended / a convenient way to add a per-file constant channel to log messages? Thanks in advance! Timo
What I"ve just done is define a logger with an attribute in each class: #define DECLARE_LOGGER(name) static ::youtils::Logger::logger_type& getLogger__() \ { \ static youtils::SeverityLoggerWithAttribute logger(name); \ return logger.get(); \ } Where: class SeverityLoggerWithAttribute { public: SeverityLoggerWithAttribute(const std::string& name, const std::string& /*subsystem*/ = "no subsystem") { logger_.add_attribute(LOGGER_ATTRIBUTE_ID, boost::log::attributes::constant<LOGGER_ATTRIBUTE_ID_TYPE>(name)); // logger_.add_attribute(LOGGER_ATTRIBUTE_SUBSYSTEM, // boost::log::attributes::constant<LOGGER_ATTRIBUTE_SUBSYSTEM_TYPE>(subsystem)); } inline Logger::logger_type& get() { return logger_; } private: Logger::logger_type logger_; }; Then I wrote some macros: #define LOG_TYPE(type, message) \ BOOST_LOG_SEV(getLogger__(), type) << __FUNCTION__ << ": " << message #define LOG_NOTIFY(message) LOG_TYPE(youtils::Severity::notification, message) So long as getLogger__ is in scope and returns the correct logger you can just LOG_XXX(whatever). You add DECLARE_LOGGER("xxx") to the class and all the member functions will do the correct logging. A mixin class that contains a logger would work equally well -- or better -- but i had to stay close to an existing architecture. So the idea is * use different loggers * make sure the LOG statements find the correct logger * Add the attribute to the logger once, and each log record will see it automatically. Regards, i On Mon, Sep 2, 2013 at 11:10 PM, Timo Schmiade <the_isz@gmx.de> wrote:
Hi all,
I want to use boost's log library to output messages to the console which feature a per-message severity and a per-file channel.
I already tried two approaches, none of which was satisfying:
=== 1. approach ===
The class boost::log::sources::severity_channel_logger supports both severity and channel and I could define it in each source file like so:
--- 8< ---
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_channel_logger< boost::log::trivial::severity_level, std::string > )
--- >8 ---
Unfortunately, using it like this requires me to redundantly add the channel to each log message, which is very inconvenient because it is the same for all logs in the file.
--- 8< ---
// Message.cpp
BOOST_LOG_CHANNEL_SEV(log, Message, trace) << "Hello, world";
--- >8 ---
=== 2. approach ===
I defined my logger like this:
--- 8< ---
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_logger< boost::log::trivial::severity_level > )
--- >8 ---
Then, in each file, I manually set the "Channel" attribute for the logger, like so:
--- 8< ---
// Message.cpp
log::get().add_attribute( "Channel", boost::log::attributes::make_constant("Message"));
--- >8 ---
This works, but as the "log" object seems to be stored globally, I would have to "invent" new names for the logger object in each file. This is both insecure and prevents the usage of macros (I think).
So here's the question:
What would be the recommended / a convenient way to add a per-file constant channel to log messages?
Thanks in advance!
Timo _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Immanuel, thanks for your answer! Reading it made me realize that my biggest flaw was trying to use the BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT macro. Using it, I was accessing the very same logger instance in every file, thus disallowing myself to have a per-file channel. This is what I came up with in the end: --- 8< --- // logging.hxx #ifndef __LOGGING_HXX__ #define __LOGGING_HXX__ #include <boost/log/trivial.hpp> #include <boost/log/sources/severity_logger.hpp> #include <boost/log/attributes/constant.hpp> // for make_constant class MyLogger : public boost::log::sources::severity_logger_mt< boost::log::trivial::severity_level > { public: MyLogger(const std::string& channel) { add_attribute( "Channel", boost::log::attributes::make_constant(channel)); } }; #define MY_LOG(severity) BOOST_LOG_SEV(::my_logger, boost::log::trivial::severity) #define DECLARE_MY_LOG(channel) \ namespace \ { \ MyLogger my_logger(#channel); \ } #endif // __LOGGING_HXX__ --- >8 --- With this, I now declare my channel name once at the top of every file (via the DECLARE_MY_LOG macro) and then use the MY_LOG macro anywhere in the code to log. Kind regards, Timo On Mon, Sep 02, 2013 at 11:10:24PM +0200, Timo Schmiade wrote:
Hi all,
I want to use boost's log library to output messages to the console which feature a per-message severity and a per-file channel.
I already tried two approaches, none of which was satisfying:
=== 1. approach ===
The class boost::log::sources::severity_channel_logger supports both severity and channel and I could define it in each source file like so:
--- 8< ---
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_channel_logger< boost::log::trivial::severity_level, std::string > )
--- >8 ---
Unfortunately, using it like this requires me to redundantly add the channel to each log message, which is very inconvenient because it is the same for all logs in the file.
--- 8< ---
// Message.cpp
BOOST_LOG_CHANNEL_SEV(log, Message, trace) << "Hello, world";
--- >8 ---
=== 2. approach ===
I defined my logger like this:
--- 8< ---
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( log, boost::log::sources::severity_logger< boost::log::trivial::severity_level > )
--- >8 ---
Then, in each file, I manually set the "Channel" attribute for the logger, like so:
--- 8< ---
// Message.cpp
log::get().add_attribute( "Channel", boost::log::attributes::make_constant("Message"));
--- >8 ---
This works, but as the "log" object seems to be stored globally, I would have to "invent" new names for the logger object in each file. This is both insecure and prevents the usage of macros (I think).
So here's the question:
What would be the recommended / a convenient way to add a per-file constant channel to log messages?
Thanks in advance!
Timo
participants (2)
-
immanuel litzroth
-
Timo Schmiade