Есть ли возможность в boost::log
рассматривать только часть сообщения журнала, если оно слишком длинное (например, 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::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
создает объект функции-оболочки, который извлекает значение атрибута сообщения из записи журнала и передает его в ваш limit_size
функция, завернутая в value_ref
справочная обертка. Если запись в журнале не содержит сообщения, справочная оболочка пуста (вот что or_none
делает). Без разницы limit_size
возврат будет выводиться в поток как часть процесса форматирования. В этом случае вы можете использовать boost::string_view
или же boost::string_ref
чтобы избежать копирования строки.
Других решений пока нет …