简体   繁体   English

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

[英]Simultaneous Logging to Console and File using Boost

I need help to initialize the boost logging framework to simultaneously log to both a named log file and also the console - (the named log file will not require periodic rotation or any of that fancy setup per many of the boost tutorials).我需要帮助来初始化 boost 日志框架以同时记录到一个命名的日志文件和控制台 - (命名的日志文件不需要定期轮换或根据许多 boost 教程进行任何花哨的设置)。

The logging text should go to both sinks simultaneously, however I need to format the console output slightly differently (as it will be viewed by a user.) I was able to get the basics of logging to 2 separate sinks working using the boost example code .日志文本应该同时进入两个接收器,但是我需要稍微不同地格式化控制台输出(因为它将被用户查看。)我能够使用boost 示例代码获得日志记录到 2 个独立接收器的基础知识. It is overly complex for what I need to do and it is really confusing as far as accessing the appropriate logger is concerned.我需要做的事情过于复杂,而且就访问适当的记录器而言,这确实令人困惑。 All I need to do is have time stamped messages sent to the log file and have the same information without the times-stamps or newlines send to the console log (putting in new lines explicitly only as I would typically do with << std::endl ).我需要做的就是将带有时间戳的消息发送到日志文件,并在没有时间戳或换行符的情况下将相同的信息发送到控制台日志(仅像我通常使用<< std::endl那样显式地放入新行) << std::endl )。 I would really like to stick with boost's logging framework as it gives the flexibility to expand in the future.我真的很想坚持使用 boost 的日志框架,因为它提供了未来扩展的灵活性。

With the example, I tried tail -f the log files - however the log output does not appear to get auto flushed after each log entry.在这个例子中,我尝试了tail -f日志文件 - 但是日志输出似乎不会在每个日志条目后自动刷新。 Although this is not very important for the file logs, this would be critical for the console output stream as it represents live activity that a user will be monitoring.尽管这对于文件日志来说不是很重要,但这对于控制台输出流至关重要,因为它代表用户将监视的实时活动。

Any help or even better, some really simple sample code to get the basics working be much appreciated.非常感谢任何帮助甚至更好的一些非常简单的示例代码来使基础工作正常工作。

The way I setup my logging (per the link above) is as shown below, I would like to replace one of these registered sinks with a console logger - but I am not sure how.我设置日志记录的方式(根据上面的链接)如下所示,我想用控制台记录器替换这些注册的接收器之一 - 但我不确定如何。 I expect that a console logger will have auto flush.我希望控制台记录器具有自动刷新功能。

// 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();

Here is some sample code that utilizes Boost-Log's global logger.下面是一些利用 Boost-Log 的全局记录器的示例代码。 I call init_term() to initialize my terminal logger and init_logfile() to initialize my logfile.我调用init_term()来初始化我的终端记录器和init_logfile()来初始化我的日志文件。

Note the auto_flush(true) call注意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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM