aruns - 2014-09-26

I am using Boost 1.54 Logging APIs and trying to change the color of the console log output. Below is the link to the minimum test code I am using (felt the code was a bit long to post directly):

http://ideone.com/o2KGw9

So, line 96 works, which is a std::cout to the console in color:

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

But when I try to do the same in boost::log::expressions::stream, in line 77, there is no color in the printed text.

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

I remember reading a post here by Andrey Semashev that it is possible to write a custom formatter that adds color control codes to the output, but AFIK that works only with Linux terminals, which is why I am trying this approach.

The way I achieved it is by giving a custom formatter function as Semasheve suggested:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 );

}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And then set the formatter for the backend like:

consolebackend->set_formatter( &my_formatter );

Unfortunately I am not using the formatting_ostream object, which makes this like a not a great solution. And the reason I couldn't use it was because of the way Boost flushes the stream. So I would get only the last color in the stream. Thus I ended up using std::cout directly.

This feels like a hack to me. So I was wondering if there was a "right" way to do it and in a thread-safe manner.

Thanks