For a long time I’ve been a big fan of console applications. Great way to put something together quickly, to see if the idea works, or simply test a piece of code or yet another library. What’s the way to see the output when you need some? They teach you that in code schools:
Console.WriteLine("Hello, world");
I was wrong and I apologize. In fact, I declare use of Console for the purpose of logging or test output to be a case of spießrutenlaufen and banished forever. Use Trace instead:
Trace.WriteLine("Hello, world");
There are multiple advantages: you can set and use levels, boolean switches are available, there are handy WriteIf and WriteLineIf functions, to name but a few. Oh, and the word itself is shorter. The most important, of course, is the concept of listeners, i.e. it’s totally up to you where to direct the output. It can be done in config file
<configuration> <system.diagnostics> <trace autoflush="false" indentsize="4"> <listeners> <add name="fileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" /> <remove name="Default" /> </listeners> </trace> </system.diagnostics> </configuration>
or straight in code
var logger = new ConsoleTraceListener(); Trace.Listeners.Add(logger);
Concept of listeners really shines when you need interaction with other libraries that also make use of tracing. Take for example, XrmTooling. If you use CrmServiceClient in your application, but something is not working and troubleshooting is required, simply do this before initializing CrmServiceClient:
var logger = new ConsoleTraceListener(); Trace.Listeners.Add(logger); TraceControlSettings.TraceLevel = SourceLevels.All; TraceControlSettings.AddTraceListener(logger); var client = new CrmServiceClient(...);
The output will light up with all sort of goodness including interesting performance bits like timing of the queries.
When using Console, output is not guaranteed either. If you try running your console code as an Azure Function on Consumption Plan (where mighty Kudu console is not avialable), good luck fishing where did Console.WriteLine go. Even though tracing in Azure Functions is different and not based on System.Diagnostics classes, it’s easy to whip your own tiny listeners as we did in Tip 808:
public class TraceWriterWrapper: TraceListener { private TraceWriter _log; public TraceWriterWrapper(TraceWriter logger) : base(name) { _log = logger; } public override void Write(string message) { _log?.Info(message); } public override void WriteLine( string message) { _log?.Info(message); } } ... public static void Run(string input, TraceWriter log) { var logger = new TraceWriterWrapper(log); Trace.Listeners.Add(logger);
and all of your trace output will reappear in the function log.
Of course, there is always Console.Beep()
if you need a sound.