使用Boost日志更改Windows控制台中日志输出的颜色

时间:2014-09-03 14:11:05

标签: c++ logging boost

我正在使用Boost 1.54 Logging API并尝试更改控制台日志输出的颜色。下面是我正在使用的最小测试代码的链接(感觉代码有点长,直接发布):

http://ideone.com/o2KGw9

因此,第96行工作,这是一个std :: cout到控制台的颜色:

std::cout << colorSet( h, DARKTEAL )<<" I am coloured!!" << colorSet( h, GRAY ) << std::endl;

但是当我尝试在boost :: log :: expressions :: stream中执行相同操作时,在第77行中,打印文本中没有颜色。

logging::formatter fmtconsole = expr::stream << colorSet( h, BLUE )<< "DEBUG:" << expr::smessage << colorSet( h, GRAY ) << "\n";

下面是我得到的输出的屏幕截图:

Console output

我记得在Andrey Semashev的Boost sourceforge论坛上阅读了一篇文章,可以编写一个自定义格式化程序,为输出添加色彩控制代码,但AFIK仅适用于Linux终端,这就是为什么我要尝试这种方法。

有没有办法实现这个目标?

感谢。

更新:

所以我实现它的方式是通过提供Semasheve建议的自定义格式化函数:

void my_formatter(logging::record_view const& rec, logging::formatting_ostream& strm)
{
    HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
    // Finally, put the record message to the stream
    boost::locale::generator gen;
    std::locale::global(gen(""));

    boost::locale::date_time now;
    std::cout.imbue(std::locale());

    std::cout << colorSet( h, BLUE ) << boost::locale::as::ftime( "%H:%M:%S" ) << "[" << now << "] ";
    std::cout << colorSet( h, RED ) << rec[expr::smessage] << colorSet( h, GRAY );

}

请参阅主代码链接以查看colorSet定义。

然后为后端设置格式化程序,如:

consolebackend->set_formatter( &my_formatter );

不幸的是我没有使用formatting_ostream对象,这使得这不是一个很好的解决方案。而我无法使用它的原因是因为Boost冲洗流的方式。所以我只得到流中的最后一种颜色。因此我最终直接使用了std :: cout。

但我确信这是可能的,不知何故。

虽然这样做了,但我仍然需要一种机制,通过这种机制,我可以将流作为临时对象获取,可以从宏中调用。

可能是这样的:

class TMP_LOG
{
    public:
    TMP_LOG(const Color& c) : col(c), m_str() { }

    ~TMP_LOG()
    {
        HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
        SetConsoleTextAttribute(h, col);

        BOOST_LOG_SEV( slg, normal ) << m_str.str();

        SetConsoleTextAttribute(h, GRAY);
    }

    std::ostringstream& stream() { return m_str; } 

private:
    std::ostringstream m_str;

    Color col;
};

#define LOG_DEBUG   TMP_LOG(RED).stream()
#define LOG_WARN    TMP_LOG(YELLOW).stream()

1 个答案:

答案 0 :(得分:1)

你可能需要写一些“懒惰操纵器”(否则它会立即评估,而不是实际写入输出流时)。

这将非常棘手。

相反,您可以使用具有ANSI功能的终端仿真器。

我选择的武器是mintty,但其他窗口也存在