Boost Log 剪切长日志消息
Boost Log cut long log messages
如果日志消息太长(例如 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)
一样定制吗?
自 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
]
)
);
装饰器将采用的格式化程序的输出限制为指定的字符数。
您也可以创建自己的格式化程序。有 的答案描述了这样做的多种方法。例如,您可以使用 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
创建了一个包装函数对象,它从日志记录中提取消息属性值并将其传递到包装在 value_ref
引用包装器中的 limit_size
函数中.如果日志记录不包含消息,则引用包装器为空(这就是 or_none
所做的)。作为格式化过程的一部分,任何 limit_size
returns 都将输出到流中。在这种情况下,您可以使用 boost::string_view
或 boost::string_ref
来避免复制字符串。
如果日志消息太长(例如 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)
一样定制吗?
自 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
]
)
);
装饰器将采用的格式化程序的输出限制为指定的字符数。
您也可以创建自己的格式化程序。有 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
创建了一个包装函数对象,它从日志记录中提取消息属性值并将其传递到包装在 value_ref
引用包装器中的 limit_size
函数中.如果日志记录不包含消息,则引用包装器为空(这就是 or_none
所做的)。作为格式化过程的一部分,任何 limit_size
returns 都将输出到流中。在这种情况下,您可以使用 boost::string_view
或 boost::string_ref
来避免复制字符串。