what's best way to use boost::log for multi-threading apps with extra 'channel' and 'id' attribute
I want to do logging in a multithreaded app to both console and file, the logging line should be like:
2011-07-18 14:48:51.849 100 CORE W : message
- 100 is unique id
- 'CORE' is a channel, I can have more channels, e.g. DATA, NETWORK.
- 'W' means warning
Currently I tried, roughly:
boost::log::sources::severity_logger< Severity > sevlogger;
enum Channel{Core, ...};
attrChannel.reset(new boost::log::attributes::mutable_constant< Channel >(Core)开发者_Go百科);
boost::log::core::get()->add_global_attribute( "Channel", *attrChannel);
...
//similar to id
...
//file sink:
typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > FileSinkType;
fileSink.reset( new FileSinkType( boost::log::keywords::file_name = fileName ));
fileSink->locked_backend()->set_formatter( format );
boost::log::core::get()->add_sink( fileSink );
...
//similar thing for console sink
...
//LOG Macro
#define LOG( ch, message )\
{\
if( ::Logging::initialized )\
{\
boost::mutex::scoped_lock _(::Logging::loggerMutex);\
unsigned int logID = ::Logging::IncrementLogID();\
::Logging::attrChannel->set(::Logging::ch);\
::Logging::attrLogID->set( logID );\
BOOST_LOG_STREAM_WITH_PARAMS((::Logging::sevlogger),\
(::boost::log::keywords::severity = ::Logging::sev )) << message;\
tls->logID = logID;\
tls->channel = ::Logging::ch;\
}\
}
It seems 'locking the mutex' is a bottleneck since I have many threads logging at the same time, but I need lock to have unique 'log id', kinda dilemma here, who can help?
I see some problems here:
1.) Declaring your own LOG-Makro
What if you change the severity level? In this case you might increment the log id but the actual log entry is not used since the appropriate severity level might be filtered out. This also causes a bit overhead while logging since nothing should be done but you still call "IncrementLogID", set(ID), set(channel) etc.
2.) To answer (hopefully) your question
I had a similar problem: I wanted using and filtering different module names, or as you call them, "channels". Add this to your stream-format:
<< "[" << expr::attr< std::string >("Channel")<< "] "
Use it like this at the beginning of a function in one of your source files belonging to "Core":
BOOST_LOG_SCOPED_THREAD_ATTR("Channel", attrs::constant< std::string >("Core"));
Of course you can replace "std::string" by your enumeration and "Core" with the enumeration value. Hope that helps!
精彩评论