Debugging. Yeah, that's roughly what the process looks like. With all those tiny symbols and all. Debug/Trace/Whatever.

Adding Debug listeners to your console application fails in .NET Core

Reading Time: 3 minutes.

Every now and then comes the need to write your console output to a log file.

There’s a simple way to do this in .NET Framework, and quite a few online articles detailing a borderline one-liner on how to do achieve it: Adding a log file listener(s) by calling Debug.Listeners – something like this:

TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);
 
TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt"));
Debug.Listeners.Add(tr2);

Source

However, this doesn’t work in .NET Core anymore.

Problem: Everything changes in .NET Core

Using the code offered by Microsoft above will lead to an error somewhat like the one below being thrown in Visual Studio:

Error CS0117 'Debug' does not contain a definition for 'Listeners' ...

What an annoyance! Another thing that has changed. Change is bad, am I right? 😉

Solution: Trace instead of Debug

.NET Core doesn’t do Debug.Listeners anymore. Now you have Trace.Listeners. However, even if you configure a listener for Trace, you won’t be getting any logging for Debug.WriteLine (or other calls thereof).

Instead, if you have Any Debug.WriteLine or System.Console.WriteLine calls in your code, and you want them to be both written to a file and shown in the console (that’s what I want, anyway), this is what you need to do:

How to configure TraceListener for your application

First, add System.Diagnostics to your using statements:

// ...
using System.Diagnostics;
 
namespace contoso.application
{
// ...

Then configure the Trace listeners like this – we’re adding both console and file tracing, so we’ll get both. Your requirements might vary.

 
        /// <summary>
        /// Let's log the execution of this console application to both
        /// console and log file!
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Log to console
            TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
            Trace.Listeners.Add(tr1);
 
            // Also log to file!
            TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText($"Log_ContosoApplication_{DateTime.Now.ToString("yyyyMMdd-HHmm")}.txt"));
            Trace.Listeners.Add(tr2);
 
            // Rest of the implementation omitted
 
            Trace.WriteLine("This will be logged to file and shown on console!");
 
            Trace.Flush();
 
            // END
        }

Then, boringly enough, replace all of your references to Debug.WriteLine with Trace.WriteLine.

Do the same for Console.WriteLine.

Now your old-fashioned Console or Debug output will instead be Traced. 😉

Oh – and before finalizing the execution of your application, please double-check that you have the code below, to make sure everything is traced!

Trace.Flush();

It was also in the code sample before, but it’s easy to miss and pretty important (otherwise you’ll miss a random number of last lines of log), so I found it worth another mention.

With that, you should have a nice log file in your execution directory for each run.

Obviously, this is a blanket solution that might not serve your needs as-is. Consider actually going through the resulting Trace.WriteLine -calls (or even the System.Console.WriteLine or Debug.WriteLine calls) before proceeding – maybe you’re logging unnecessary data, thus possibly eventually clogging your storage – or figuring out a way to clean up old logs?

Anyway – that’s all for today.

References

On a related note, for a guide on how to simply output/redirect all of the output of a console application or a PowerShell script to a file (especially if you don’t have access to the codebase!), see the article below:


mm

Leave a Reply

avatar
5000
  Subscribe  
Notify of