Как добавить цветовую кодировку для вывода на консоль boost::log?

Я пытаюсь добавить цветной вывод журнала для boost:: log под Linux. Я прочитал следующее, и я попробовал это:

#define MY_LOG_ERROR() BOOST_LOG_TRIVIAL(error) << "\033[1;31"

MY_LOG_ERROR() << "This is an error log."

но это дает мне результат ниже:

[2016-07-11 17: 23: 16.328435] [0x00007f15f03d6780] [ошибка] [1;31 Это журнал ошибок.

Как правильно добавить цветной вывод журнала в boost::log?

2 ответа

Решение

Правильный способ настроить вывод с помощью Boost.Log - использовать средства форматирования. Чтобы установить форматтер, вам нужно настроить приемник для этого, как описано здесь, но вы можете продолжать использовать BOOST_LOG_TRIVIAL макрос для создания записей журнала.

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

void coloring_formatter(
    logging::record_view const& rec, logging::formatting_ostream& strm)
{
    auto severity = rec[logging::trivial::severity];
    if (severity)
    {
        // Set the color
        switch (severity.get())
        {
        case logging::trivial::severity::info:
            strm << "\033[32m";
            break;
        case logging::trivial::severity::warning:
            strm << "\033[33m";
            break;
        case logging::trivial::severity::error:
        case logging::trivial::severity::fatal:
            strm << "\033[31m";
            break;
        default:
            break;
        }
    }

    // Format the message here...
    strm << rec[logging::expressions::smessage];

    if (severity)
    {
        // Restore the default color
        strm << "\033[0m";
    }
}

sink->set_formatter(&coloring_formatter);

Я недавно сделал это с простым пользовательским бэкэндом

coloured_console_sink.h

#pragma once
#include <boost/log/sinks/basic_sink_backend.hpp>

class coloured_console_sink : public boost::log::sinks::basic_formatted_sink_backend<char, boost::log::sinks::synchronized_feeding>
{
public:
    static void consume(boost::log::record_view const& rec, string_type const& formatted_string);
};

coloured_console_sink.cpp

#include "coloured_console_sink.h"
#include <iostream>
#include <windows.h>
#include <boost/log/trivial.hpp>
#include <boost/log/attributes/value_extraction.hpp>
#include <boost/log/attributes/attribute_value.hpp>

WORD get_colour(boost::log::trivial::severity_level level)
{
    switch (level)
    {
        case boost::log::trivial::trace: return 0x08;
        case boost::log::trivial::debug: return 0x07;
        case boost::log::trivial::info: return 0x0F;
        case boost::log::trivial::warning: return 0x0D;
        case boost::log::trivial::error: return 0x0E;
        case boost::log::trivial::fatal: return 0x0C;
        default: return 0x0F;
    }
}

void coloured_console_sink::consume(boost::log::record_view const& rec, string_type const& formatted_string)
{
    auto level = rec.attribute_values()["Severity"].extract<boost::log::trivial::severity_level>();
    auto hstdout = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hstdout, &csbi);

    SetConsoleTextAttribute(hstdout, get_colour(level.get()));
    std::cout << formatted_string << std::endl;
    SetConsoleTextAttribute(hstdout, csbi.wAttributes);
}

использование

typedef boost::log::sinks::synchronous_sink<coloured_console_sink> coloured_console_sink_t;
auto coloured_console_sink = boost::make_shared<coloured_console_sink_t>();

boost::log::core::get()->add_sink(coloured_console_sink);
Другие вопросы по тегам