Решение вашей проблемы во многом зависит от характера данных, как вы хотите использовать зарегистрированные данные.
1. Пересмотрите возможность преобразования двоичных данных в текст
В целях отладки часто удобнее преобразовать двоичные данные в текст. Даже при больших объемах данных этот подход может быть полезен, поскольку инструментов для обработки текста обычно намного больше, чем для работы с произвольными двоичными данными. Например, вы можете сравнить два журнала из разных запусков вашего приложения с помощью обычных инструментов слияния/сравнения, чтобы увидеть разницу. Текстовые журналы также легче фильтровать с помощью таких инструментов, как grep
или awk
, которые легко доступны, в отличие от двоичных данных, для которых вам, вероятно, придется писать анализатор.
Есть много способов преобразовать двоичные данные в текст. Самый прямой подход — использовать dump
манипулятор, который будет эффективно создавать текстовое представление необработанных двоичных данных. Он также подходит для графических данных, потому что они, как правило, относительно велики по объему, и их часто достаточно легко сравнивать в текстовом представлении (например, когда образец цвета соответствует байту).
std::vector< std::uint8_t > image;
// Outputs hex dump of the image
BOOST_LOG_TRIVIAL(info) << logging::dump(image.data(), image.size());
Более структурированный способ вывода двоичных данных — использование других библиотек, таких как iterator_range
из Boost.Range. Это может быть полезно, если ваши графические данные состоят из чего-то более сложного, чем необработанные байты.
std::vector< double > image;
// Outputs all elements of the image vector
BOOST_LOG_TRIVIAL(info) << boost::make_iterator_range(image);
Вы также можете написать свой собственный манипулятор, который будет форматировать данные так, как вы хотите, например. разбить вывод по строкам.
2. Для двоичных данных используйте атрибуты и пользовательский бэкенд приемника.
Если вы намерены обрабатывать зарегистрированные данные с помощью более специализированного программного обеспечения, такого как средство просмотра изображений или редактор, вы можете сохранить данные в двоичной форме. Это можно сделать с помощью Boost.Log, но это потребует больше усилий, потому что приемники, предоставляемые библиотекой, ориентированы на текст, и вы не можете сохранить двоичные данные в текстовый файл как есть. Вам нужно будет написать серверную часть приемника, которая будет записывать двоичные данные в нужном вам формате (например, если вы планируете использовать редактор изображений, вы можете захотеть записывать файлы в формате, поддерживаемом этим редактором). Существует руководство здесь, где показан интерфейс, который необходимо реализовать, и пример реализации. Важным битом является функция consume
бэкэнда, которая получит представление записи журнала с вашими данными.
typedef boost::iterator_range< const double* > image_data;
BOOST_LOG_ATTRIBUTE_KEYWORD(a_image, "Image", image_data)
class image_writer_backend :
public sinks::basic_sink_backend< sinks::synchronized_feeding >
{
public:
void consume(logging::record_view const& rec)
{
// Extract the image data from the log record
if (auto image = rec[a_image])
{
image_data const& im = image.get();
// Write the image data to a file
}
}
};
Чтобы передать двоичные данные вашего изображения в ваш приемник, вам нужно будет прикрепить их к записи журнала в качестве атрибута. Есть несколько способов сделать это, но если вы не собираетесь фильтровать записи журнала на основе изображения, самый простой способ сделать это — использовать add_value
манипулятор.
std::vector< double > image;
BOOST_LOG_TRIVIAL(info) << logging::add_value(a_image, image) << "Catch my image";
Предостережение: чтобы избежать копирования потенциально больших данных изображения, мы передаем упрощенное значение iterator_range
в качестве значения атрибута. Это будет работать только с синхронным ведением журнала, поскольку вектор image
должен оставаться активным, пока обрабатывается запись журнала. Для асинхронного ведения журнала вам придется передавать изображение по значению или использовать подсчет ссылок.
Если вы хотите применить фильтры к данным изображения, вы можете использовать атрибуты с областью действия или добавьте атрибут в регистратор.
Обратите внимание, что, добавляя новый приемник для записи двоичных данных, вы не исключаете записи текстовых журналов с другими приемниками, чтобы сообщение «Catch my image» могло быть обработано текстовым приемником. Используя другие атрибуты, такие как запись журнала счетчики вы можете связать записи журнала в разных файлах, созданных разными приемниками.
person
Andrey Semashev
schedule
18.09.2017