【问题标题】:How to prevent boost logger to add \n after each record?如何防止boost logger在每条记录后添加\ n?
【发布时间】:2019-06-05 11:35:27
【问题描述】:

我们已经重构了我们的记录器以使用 boost 而不是我们内部的记录器,它不是线程安全的。问题是我们围绕项目的所有日志调用(数千行代码)都以std::endl 结尾。现在,我们的记录器是线程安全的,但是输出的记录之间有一个额外的空行。 这就是我初始化记录器的方式:

void init()
{
    boost::log::add_console_log
    (
        std::clog,
        boost::log::keywords::format =
        (
                boost::log::expressions::stream << boost::log::expressions::format_date_time<     boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
                << " [" << boost::log::expressions::attr<     LogLevel_e >("Severity") << "]: "
                << boost::log::expressions::smessage
        )
    );
}

它是一个用于记录我们的消息的 severity_logger_mt() 对象。 我在他们的文档中读到,如果我创建自己的后端和前端,我可能能够防止出现空行。为了防止代码中出现多余的空行而创建两个模块似乎太麻烦了。

我错过了什么吗?有更简单的方法吗?我应该为这个问题添加更多信息吗? 另外,我们谈论的是 boost 1.69。

【问题讨论】:

    标签: c++ logging boost


    【解决方案1】:

    换行符由接收器后端自动添加。修复它的“正确”方法是更改​​您的日志记录语句,以便它们不会以换行符结束消息字符串。我认为这是正确的方法,因为尾随换行符是否有意义取决于接收器后端。同一个日志记录可以被多个 sink 处理,换行可能并不适合所有的 sink。

    但是,作为一种更快的解决方法,您可以编写自己的格式化程序,它会跳过格式化字符串中的尾随换行符。有许多答案展示了如何编写格式化程序(例如,here)。这是执行此操作的一种方法:

    std::string_view format_message(
        boost::log::value_ref< std::string, boost::log::expressions::tag::smessage > const& message)
    {
        // Check to see if the attribute value has been found
        if (message)
        {
            std::string_view msg = message.get();
            if (!msg.empty() && msg.back() == '\n')
                msg = std::string_view(msg.data(), msg.size() - 1);
            return msg;
        }
    
        return std::string_view();
    }
    
    void init()
    {
        boost::log::add_console_log
        (
            std::clog,
            boost::log::keywords::format =
            (
                boost::log::expressions::stream
                    << boost::log::expressions::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
                    << " [" << boost::log::expressions::attr< LogLevel_e >("Severity") << "]: "
                    << boost::phoenix::bind(&format_message, boost::log::expressions::smessage.or_none())
            )
        );
    }
    

    【讨论】:

    • 这段代码有点麻烦。我试图将它集成到项目中,但我得到一个异常错误转换和这段代码:proto::make_expr(a...)。我应该包含来自 boost 的其他模块吗?这里还有什么其他的改变吗?似乎仍然存在一些不兼容。我正在尝试自己解决它,但如果您能对此提供一些见解,将不胜感激。谢谢!
    • 到目前为止我已经包含了这两个:#include #include
    • 我已经更正了代码示例。重要的变化是:在format_message 签名中使用tag::smessage 来匹配smessage 关键字,并在格式化程序中使用smessage.or_none() 构造来解决Boost.Phoenix 的限制。要使用boost::phoenix::bind,您应该包含&lt;boost/phoenix/bind.hpp&gt;
    猜你喜欢
    • 2017-11-04
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多