Настроить Boost.Log v2

Я использую Boost.Log V2 1.75.0 и настраиваю свою среду из файла конфигурации с помощью boost::log::init_from_stream(config);

Можно ли объявить цветной приемник консоли через файл конфигурации или есть ли способ добавить цветной вывод в консоль?

Теперь я добавляю столько приемников консоли, сколько уровней журнала доступно в Boost Trivial Logger, и фильтрую их по разным уровням, но я не думаю, что это правильный путь. Пример:

[Sinks.ConsoleSinkTrace]
Destination=Console
Filter="%Severity% = trace"
Format="\033[0;35m[%TimeStamp%] [%ProcessId%] [%ThreadId%] [%Severity%] - %Message%\033[0m"
Asynchronous=false
AutoFlush=true

[Sinks.ConsoleSinkDebug]
Destination=Console
Filter="%Severity% = debug"
Format="\033[0;34m[%TimeStamp%] [%ProcessId%] [%ThreadId%] [%Severity%] - %Message%\033[0m"
Asynchronous=false
AutoFlush=true

... и так далее...

Обновить

Я нашел сообщение SO, предложенное @AndreySemashev, но я действительно не понимаю, как я могу приспособить его к своему проекту: мое основное ожидание состоит в том, что я хочу настроить Boost.Log через файл, поэтому:

  1. если я вообще удалю приемник консоли из файла конфигурации, как установить средство форматирования в приемник? (Я предполагаю, что sink - это приемник консольного типа, который не будет создан, если в файле конфигурации нет такого раздела)

раковина-›set_formatter(&coloring_formatter);

  1. если я предоставлю новый метод форматирования, я предполагаю, что обработка всей строки формата, указанной в файле конфигурации, является моей ответственностью. я тоже хочу этого избежать

Верны ли эти наблюдения, или я что-то упускаю?

Спасибо


person Moravas    schedule 14.03.2021    source источник


Ответы (1)


Создание модуля форматирования с поддержкой раскраски описано в другом ответе, здесь я сосредоточусь на том, как включить этот модуль форматирования в файл настроек. .

Boost.Log поддерживает расширение анализатора файлов настроек с помощью регистрация заводов-приемников, которые вы можете использовать в своем случае. Поскольку вы можете повторно использовать text_ostream_backend для вывода, вам не нужно реализовывать новый приемник, но вам нужно настроить его конфигурацию.

class colored_console_factory :
    public logging::sink_factory< char >
{
public:
    // Creates the sink with the provided parameters
    boost::shared_ptr< sinks::sink > create_sink(settings_section const& settings)
    {
        typedef sinks::text_ostream_backend backend_t;
        auto backend = boost::make_shared< backend_t >();

        backend->add_stream(
            boost::shared_ptr< std::ostream >(&std::clog, boost::null_deleter()));

        // Read settings and configure the backend accordingly
        if (auto auto_flush = settings["AutoFlush"])
            backend->auto_flush(*auto_flush == "1" || *auto_flush == "true");

        auto sink =
            boost::make_shared< sinks::synchronous_sink< backend_t > >(backend);

        // You can reuse filter and formatter parsers provided by Boost.Log
        if (auto filter = settings["Filter"])
            sink->set_filter(logging::parse_filter(*filter));

        if (auto format = settings["Format"])
        {
            logging::formatter fmt = logging::parse_formatter(*format);
            // Wrap the parsed formatter with coloring
            sink->set_formatter(coloring_formatter(std::move(fmt)));
        }

        return sink;
    }
};

В приведенном выше примере coloring_formatter — это объект функции, который оборачивает проанализированный модуль форматирования с префиксом и суффиксом окраски в выходных данных. Объект функции должен иметь стандартную подпись средства форматирования.

class coloring_formatter
{
public:
    typedef void result_type;
    typedef basic_formatting_ostream< char > stream_type;

public:
    explicit coloring_formatter(logging::formatter&& fmt) :
        m_fmt(std::move(fmt))
    {}

    result_type operator() (
        logging::record_view const& rec, stream_type& strm) const
    {
        // Output coloring prefix
        auto severity = rec[logging::trivial::severity];
        if (severity)
        {
            switch (severity.get())
            {
                ...
            }
        }

        // Let the wrapped formatter produce its output
        m_fmt(rec, strm);

        // Output coloring suffix
        if (severity)
        {
            ...
        }
    }

private:
    logging::formatter m_fmt;
};

Обратитесь к ответу, который я упоминал ранее, для получения подробной информации о реализации coloring_formatter.

person Andrey Semashev    schedule 15.03.2021
comment
Спасибо @AndreySemashev. Я думаю, добавление поддержки этого приемника в библиотеку было бы кстати. - person Moravas; 16.03.2021