How to Enable Logging in .NET Console Applications

We have seen in the previous few posts that Generic host is a concept that encapsulates configuration, logging, dependency injection and IHostedService implementations.

So, if the .NET console application has the need of logging, then obvious way is to create the host. What if you do not want to create a host in your console application ? There is also another way. Let’s see what are two different ways to enable logging in .NET console apps.

Host Based Console App

For host based console app, it is very straight forward. It is a two step process:

NuGet Packages

There are three NuGet packages which can be added to the console application.

Code

Below is an example of adding a SimpleConsole provider, which logs all messages to the console. The code is also adding EventLog as the logging provider, which logs all logged messages to the event viewer. You can open EventViewer app on windows to view the logged messages.

class Program
{
    static Task Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        var workerInstance = host.Services.GetRequiredService<Worker>();
        workerInstance.Execute();
        return host.RunAsync();
    }

    static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .ConfigureServices((_, services) =>
        {
            services.AddTransient<Worker>();
        })
        .ConfigureLogging((_, logging) => 
        {
            logging.ClearProviders();
            logging.AddSimpleConsole(options => options.IncludeScopes = true);
            logging.AddEventLog();
        });
}

Non-Host Console App

This type of console app does not setup the generic host. Instead, we are going to use LoggerFactory.Create to build the logger instances. This method takes Action parameter which can be used to configure logging providers.

NuGet Packages

Below NuGet packages should be added to the console application.

Code

Below is an example code which creates LoggerFactory instance to create the ILogger instances.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("NonHostConsoleApp.Program", LogLevel.Debug)
                .AddConsole();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Info Log");
        logger.LogWarning("Warning Log");
        logger.LogError("Error Log");
        logger.LogCritical("Critical Log");
        Console.ReadLine();
    }
}

Opinions – Pros & Cons

In my opinion, the approach with Host scales better. If you have a decent sized console application, it would need configuration file, you might want to use dependency injection and other features too. These features are easy to implement using Host based console application.

Creating host might be a lot if you are creating a simple console application, which is either very small, or has shorter lifecycle. If the application has only couple of classes and very limited logic, then it might be better idea to use the Non-Host console app approach.

My two cents, when you start on any app, it appears to be very simple. If it has great utility, people keep adding code to it and it grows over the time, even thought that was not envisioned initially. So, if I am confused which type of console app should be used, I would probably prefer Host based approach.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *