0

I need to add coloring to boost log on Windows. Very simple - if error - use red ink, if warning - yellow ink, otherwise - white. No point to quote my code. I used exactly this solution (2nd answer, I suppose 1st answer is for Linux only):

How to add color coding to boost::log console output?

I found few others, but all are based on the same principle - set console foreground color, using win32 api and do that in a sink. Problem is that it's not good. If log is receiving messages from multiple sources, sometimes color is applied to a fragment (not even a full) line and often another line (previous or next). I declared sink as synchronous (with asynchronous, coloring looked like a drawing of a mad man). Is there any way to stabilize / fix that?

Voitek

Vojtek
  • 31
  • 4
  • Are you logging from a single thread? Seems like you have synchronization issue and colors being wrong is just a side effect. – Jeffrey Nov 19 '19 at 13:47
  • No. From many threads. Each thread live it's own life. But the log is one. For the entire application. Is boost::log not thread-safe? I was sure it can queue messages from multiple threads... – Vojtek Nov 19 '19 at 13:49

1 Answers1

0

Even though your logging function is thread-safe, using it might still require synchronisation.

Consider two threads, each doing one of the below:

  1. strm << red << "message";
  2. strm << white << "other message";

The scheduler might schedule

  • thread 1 does strm << red
  • thread 2 does strm << white
  • thread 1 does strm << "message"
  • thread 2 does strm << "other message"

You get "message" followed by "other message", both in white. This is still considered thread-safe and OK.

One first option is to concatenate the message, colored, in a single string and provide it to your logging API:

strm << red + "message";. You'll need to fix this line so that red is a std:string or something that can be concatenated with "message". But the important part is that the loggin API gets a single call with color and content in a single go.

A second option is to put a single mutex around each logging block where you submit colors and text.

Jeffrey
  • 11,063
  • 1
  • 21
  • 42
  • Unfortunately nothing from this answer is usable. I can't add some special characters in Windows to color the text. coloring is available only through win32 api. As for the second suggestion - the mutex - this is not working as well. Problem here is that stream is not flushed inside a sink function. It's flushed outside of it. – Vojtek Nov 23 '19 at 12:13
  • Then lock a mutex before the first `SetConsoleTextAttribute` and unlock it after the std::cout and second `SetConsoleTextAttribute`. – Jeffrey Nov 23 '19 at 13:06