使用Boost同时登录到控制台和文件

时间:2014-06-11 19:00:26

标签: c++ logging boost boost-log boost-logging

我需要帮助来初始化boost日志框架,以同时登录到命名日志文件和控制台 - (命名日志文件不需要定期轮换或每个升级教程的任何花哨设置)。

日志记录文本应同时转到两个接收器(文件和控制台),但是我需要稍微改变控制台输出的格式,因为用户将查看它。我能够使用 boost example code 获取使用2个独立接收器记录的基础知识。对于我需要做的事情来说过于复杂,就访问适当的记录器而言,这实在令人困惑。我需要做的就是将带有时间戳的消息发送到日志文件并且具有相同的信息,而不会将时间戳或换行符发送到控制台日志(只显示新的行,就像我通常使用<< std一样:: endl流媒体操作)。我真的很想坚持使用boost的日志框架,因为它可以灵活地在未来扩展。

通过该示例,我尝试使用tail -f日志文件 - 但是在每个日志条目之后,日志输出似乎不会自动刷新。虽然这对于文件日志来说不是很重要,但这对于控制台输出流至关重要,因为它表示用户将要监视的实时活动。

任何帮助,甚至更好,一些非常简单的示例代码,以获得基本工作非常感谢。

我设置日志记录的方式(按照上面的链接)如下所示,我想用控制台记录器替换其中一个注册的接收器 - 但我不知道如何。我希望控制台记录器能够自动刷新。

// Setup the common formatter for all sinks
logging::formatter fmt = expr::stream
    << std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
    << ": <" << severity << ">\t"
    << expr::if_(expr::has_attr(tag_attr))
    [
        expr::stream << "[" << tag_attr << "] "
    ]
<< expr::smessage;

// Initialize sinks
typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink;
boost::shared_ptr<text_sink> sink = 
    boost::make_shared<text_sink>();
sink->locked_backend()->add_stream(
    boost::make_shared<std::ofstream>(
        "full.log"));
sink->set_formatter(fmt);
// register the full log sink
logging::core::get()->add_sink(sink);

sink = boost::make_shared<text_sink>();
sink->locked_backend()->add_stream(
    boost::make_shared<std::ofstream>(
        "important.log"));
//    sink->set_formatter(fmt); (I removed this to not have any special formatting hopefully)
sink->set_filter(severity >= warning || 
    (expr::has_attr(tag_attr) && 
    tag_attr == "IMPORTANT_MESSAGE"));
// register the important log sink
logging::core::get()->add_sink(sink);
// Add attributes
logging::add_common_attributes();

1 个答案:

答案 0 :(得分:4)

以下是一些使用Boost-Log全局记录器的示例代码。我打电话给init_term() 初始化我的终端记录器和init_logfile()以初始化我的日志文件。

请注意auto_flush(true)来电

// Logging macro
#define LOG(level) BOOST_LOG_SEV(global_logger::get(), level)
// Initializing global boost::log logger
typedef boost::log::sources::severity_channel_logger_mt<
    severity_level, std::string> global_logger_type;

BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(global_logger, global_logger_type)
{
    return global_logger_type(boost::log::keywords::channel = "global_logger");
}

// Initialize terminal logger
void init_term()
{
    // create sink to stdout
    boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
    sink->locked_backend()->add_stream(
        boost::shared_ptr<std::ostream>(&out, boost::empty_deleter()));

    // flush
    sink->locked_backend()->auto_flush(true);

    // format sink
    sink->set_formatter
    (
        /// TODO add your desired formatting
    );

    // filter
    // TODO add any filters

    // register sink
    bl::core::get()->add_sink(sink);
}

// Initialize logfile
void init_logfile(const std::string& logfilename)
{
    // create sink to logfile
    boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
    sink->locked_backend()->add_stream(
        boost::make_shared<std::ofstream>(logfilename.c_str()));

    // flush
    sink->locked_backend()->auto_flush(true);

    // format sink
    sink->set_formatter
    (
        /// TODO add your desired formatting
    );

    // filter
    // TODO add any filters

    // register sink
    bl::core::get()->add_sink(sink);
}