I have the simple function
let OutputDebugToConsole () =
new System.Diagnostics.TextWriterTraceListener(System.Console.Out)
|> System.Diagnostics.Debug.Listeners.Add |> ignore
to redirect the debug output from Debug.WriteLine
to the console.
I wish to have the debug output in a different colour, by setting Console.ForegroundColor
to gray, for example. Obviously the colour needs to be reset after each writing for normal text to be written in standard colours. My idea is to pass a different TextWriter
that decorates the Write
method.
First, is this a sensible way of thinking about the problem? Second, to do this would I need to rewrite all methods of my TextWriter
or is there a different way?
Console.ForegroundColor has both a property getter and setter so it is technically possible to simply store the old color, assign it, write and restore the old color.
It is however not thread-safe to do so. Another thread may also use Console.Write and assign the ForegroundColor property to get its own preferred color. That's a race, your logger may end up writing with the color selected by the other thread. And the other way around. There's a lock that prevents both threads writing text to the console and get their output intermingled, but it is taken too late. There is no simple way to solve that, other than having your logger using pinvoke so that it doesn't need to use ForegroundColor at all.
That's a fugly little detail if there ever was one. That's why it is usually better to use a logging library that takes care of these nasty little details. NLog for example.
You can implement this in a fairly straightforward way using the Printf.kprintf
function, as demonstrated in this blog post: Colored printf
Basically, Printf.kprintf
accepts a continuation which the formatted string is applied to; the blog post I linked shows how you can pass a continuation which sets the console color, prints the string, then restores the original color before returning.
As Hans Passant wrote in his answer, there are thread-safety issues with setting/restoring the console color so you should be sure to design your application accordingly (if you're using multiple threads or the F# async
workflow).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With