【问题标题】:Boost Log cut long log messagesBoost Log 截断长日志消息
【发布时间】:2016-09-13 20:10:58
【问题描述】:

如果日志消息太长(例如 1000 个字符),boost::log 是否有可能只考虑日志消息的一部分?这在跟踪可变内容时很有用,因为它的全部不是必须找出所需的信息。

例如:当从当前目录打印带有文件列表的字符串时,我不需要查看整个列表即可知道文件系统是否扫描成功。

boost::log::add_file_log
(
    boost::log::keywords::file_name = "logs/Log_%Y-%m-%d_%H-%M-%S.log",
    boost::log::keywords::rotation_size = 10 * 1024 * 1024,
    boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
    boost::log::keywords::auto_flush = true,
    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:%f")
        << " [" << boost::log::expressions::attr<boost::log::attributes::current_thread_id::value_type>("ThreadID") << "]"
        << ": <" << boost::log::trivial::severity << "> " 
        << boost::log::expressions::smessage
    )
);

例如:boost::log::expressions::smessage 是否可以像 boost::log::expressions::smessage::substr(0, 1000) 或其他任何方式进行自定义?

【问题讨论】:

    标签: c++ boost boost-log


    【解决方案1】:

    自 Boost 1.62 以来,有一个 max_size_decor 装饰器可以满足您的要求。你可以这样使用它:

    boost::log::add_file_log
    (
        boost::log::keywords::file_name = "logs/Log_%Y-%m-%d_%H-%M-%S.log",
        boost::log::keywords::rotation_size = 10 * 1024 * 1024,
        boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
        boost::log::keywords::auto_flush = true,
        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:%f")
            << " [" << boost::log::expressions::attr<boost::log::attributes::current_thread_id::value_type>("ThreadID") << "]"
            << ": <" << boost::log::trivial::severity << "> " 
            << boost::log::expressions::max_size_decor(1000)
            [
                boost::log::expressions::stream << boost::log::expressions::smessage
            ]
        )
    );
    

    装饰器将采用的格式化程序的输出限制为指定的字符数。

    您还可以创建自己的格式化程序。有this 回答描述了多种方法。例如,您可以使用 boost::phoenix::bind 来包装您的函数来限制大小:

    boost::string_view limit_size(boost::log::value_ref<
        std::string, boost::log::expressions::tag::smessage > const& message)
    {
        if (!message)
        {
            // No message attribute in the log record
            return boost::string_view();
        }
    
        boost::string_view msg = message.get();
        return msg.substr(0, 1000);
    }
    
    boost::log::add_file_log
    (
        boost::log::keywords::file_name = "logs/Log_%Y-%m-%d_%H-%M-%S.log",
        boost::log::keywords::rotation_size = 10 * 1024 * 1024,
        boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
        boost::log::keywords::auto_flush = true,
        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:%f")
            << " [" << boost::log::expressions::attr<boost::log::attributes::current_thread_id::value_type>("ThreadID") << "]"
            << ": <" << boost::log::trivial::severity << "> " 
            << boost::phoenix::bind(&limit_size, boost::log::expressions::smessage.or_none())
        )
    );
    

    在此示例中,phoenix::bind 创建了一个包装函数对象,该对象从日志记录中提取消息属性值并将其传递给您的 limit_size 函数,该函数包装在 value_ref 引用包装中。如果日志记录不包含消息,则引用包装器为空(or_none 就是这样做的)。无论limit_size 返回什么,都将作为格式化过程的一部分输出到流中。在这种情况下,您可以使用boost::string_viewboost::string_ref 来避免复制字符串。

    【讨论】:

      猜你喜欢
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2021-01-01
      • 2019-12-13
      相关资源
      最近更新 更多