C++ 什么';对于多线程应用程序,使用boost::log的最佳方法是使用额外的';频道';和';id';属性

C++ 什么';对于多线程应用程序,使用boost::log的最佳方法是使用额外的';频道';和';id';属性,c++,boost,logging,C++,Boost,Logging,我想在多线程应用程序中对控制台和文件进行日志记录,日志记录行应该如下所示: 2011-07-18 14:48:51.849 100核心W:信息 100是唯一的id “核心”是一个通道,我可以有更多通道,例如数据、网络 “W”表示警告 目前,我大致尝试了: boost::log::sources::severity_logger< Severity > sevlogger; enum Channel{Core, ...}; attrChannel.reset(new boost::l

我想在多线程应用程序中对控制台和文件进行日志记录,日志记录行应该如下所示:

2011-07-18 14:48:51.849 100核心W:信息

  • 100是唯一的id
  • “核心”是一个通道,我可以有更多通道,例如数据、网络
  • “W”表示警告
  • 目前,我大致尝试了:

    boost::log::sources::severity_logger< Severity > sevlogger;
    
    enum Channel{Core, ...};
    attrChannel.reset(new boost::log::attributes::mutable_constant< Channel >(Core));
    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;\
                }\
            }
    
    boost::log::sources::severity\u loggersevlogger;
    枚举通道{Core,…};
    重置(新的boost::log::attributes::可变_常量(核心));
    boost::log::core::get()->添加全局属性(“通道”,*attrChannel);
    ...
    //类似于id
    ...
    //文件接收器:
    typedef boost::log::sinks::synchronous_sinkFileSinkType;
    reset(新的FileSinkType(boost::log::keywords::file_name=fileName));
    fileSink->locked_backend()->set_格式化程序(格式);
    boost::log::core::get()->add_sink(fileSink);
    ...
    //控制台水槽也是如此
    ...
    //日志宏
    #定义日志(ch,消息)\
    {\
    如果(::日志记录::已初始化)\
    {\
    boost::mutex::作用域锁定(Logging::loggerMutex)\
    unsigned int logID=::Logging::IncrementLogID()\
    ::Logging::attrChannel->set(::Logging::ch)\
    ::Logging::attrLogID->set(logID)\
    使用参数((::Logging::sevlogger)提升日志流\
    (::boost::log::keywords::severity=::Logging::sev))logID=logID\
    tls->channel=::Logging::ch\
    }\
    }
    

    “锁定互斥锁”似乎是一个瓶颈,因为我有许多线程同时登录,但我需要锁来拥有唯一的“日志id”,这有点进退两难,谁能帮忙?

    我在这里看到一些问题:

    1.)声明您自己的日志Makro

    如果更改严重性级别会怎么样?在这种情况下,您可能会增加日志id,但不会使用实际日志条目,因为可能会过滤掉相应的严重性级别。这也会导致日志记录时的一些开销,因为不应该执行任何操作,但仍然可以调用“IncrementLogID”、set(ID)、set(channel)等

    2.)回答(希望)你的问题

    我有一个类似的问题:我想使用和过滤不同的模块名,或者你称之为“通道”。将其添加到流格式:

    << "[" << expr::attr< std::string >("Channel")<< "] "
    

    我在日志库中也使用了全局日志互斥(等待boost.log正式发布)。这确实成为了一个瓶颈,我真的没有更好的技术。我的解决方案是只记录与我试图跟踪的问题或再次出现的问题相关的信息。希望随着项目的临近,所需的执行跟踪量接近于零release@totowtwo谢谢,我真正想知道的是:应该有一种方法不需要“保护那些属性”,比如在我的例子中,“通道”和“日志id”应该像“函数参数”一样传递。
    
    BOOST_LOG_SCOPED_THREAD_ATTR("Channel", attrs::constant< std::string >("Core"));