Microsoft.Extensions.Logging Fundamentals

This document provides a comprehensive overview of the Microsoft.Extensions.Logging package, a fundamental component for logging in .NET applications. Learn how to configure, use, and extend the logging infrastructure to gain visibility into your application's behavior.

Effective logging is crucial for understanding application state, diagnosing issues, and monitoring performance. The Microsoft.Extensions.Logging abstraction provides a unified way to log messages across different application types, from console applications to web services and desktop applications.

Key Concepts

The ILogger Interface

The core of the logging abstraction is the ILogger<TCategoryName> interface. It provides methods for logging messages at various severity levels (e.g., LogInformation, LogWarning, LogError). The generic type parameter TCategoryName is typically the name of the class where the logger is being used, helping to categorize log messages.


using Microsoft.Extensions.Logging;

public class MyService
{
    private readonly ILogger<MyService> _logger;

    public MyService(ILogger<MyService> logger)
    {
        _logger = logger;
    }

    public void DoSomething()
    {
        _logger.LogInformation("Performing a critical operation.");
        // ... operation logic ...
        _logger.LogWarning("Operation might encounter potential issues.");
        try
        {
            // ... risky operation ...
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred during the operation.");
        }
    }
}
            

LoggerFactory and Providers

The ILoggerFactory is responsible for creating instances of ILogger. It works with logging providers, which are implementations that route log messages to specific destinations like the console, files, databases, or external logging services (e.g., Application Insights, Serilog, NLog).

In modern .NET applications, the ILoggerFactory is typically managed by the dependency injection container.

Log Levels

Logging operates with different levels to categorize the severity of messages:

You can configure the minimum log level to control which messages are processed by the logging providers.

Configuring Logging

In ASP.NET Core

ASP.NET Core applications have built-in support for logging configuration within the Program.cs file (or Startup.cs in older versions). The CreateHostBuilder method sets up the host, including the logging configuration.


// Program.cs (ASP.NET Core 6+)
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

// Configure logging - example: set minimum log level and add console provider
builder.Logging.SetMinimumLevel(LogLevel.Information);
builder.Logging.AddConsole();

var app = builder.Build();

// ... rest of the application configuration ...

app.Run();
            

In Worker Services and Console Applications

Similar configuration patterns apply to generic host applications like worker services.


// Program.cs (Worker Service/Console App)
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders(); // Remove default providers if desired
                logging.AddConsole();     // Add console logging
                logging.AddDebug();       // Add debug logging

                // Set minimum log level for all providers
                logging.SetMinimumLevel(LogLevel.Debug);

                // Configure specific provider minimum levels or filters
                // logging.AddFilter("Microsoft", LogLevel.Warning);
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<MyWorkerService>();
            });
}
            

Common Logging Providers

Console Logger

Logs messages to the console. It's useful for development and debugging.

To use the Console logger, add logging.AddConsole(); to your configuration.

Debug Logger

Logs messages to the debugger's output window.

To use the Debug logger, add logging.AddDebug(); to your configuration.

Event Log Logger

Logs messages to the Windows Event Log.

To use the Event Log logger, add logging.AddEventLog(); to your configuration. This provider is specific to Windows environments.

Extending Logging

Creating Custom Providers

You can create your own logging providers to send logs to custom destinations, such as a specific API, a message queue, or a proprietary logging system. This involves implementing the ILoggerProvider interface.

Using Third-Party Libraries

Many popular logging frameworks integrate seamlessly with Microsoft.Extensions.Logging. Popular choices include:

To use these, you typically install the relevant NuGet package and configure it as a logging provider. For example, with Serilog:


// Install Serilog.Extensions.Logging and Serilog.Sinks.Console
// ... in Program.cs or Startup.cs ...
builder.Host.UseSerilog((context, configuration) =>
{
    configuration.ReadFrom.Configuration(context.Configuration)
        .WriteTo.Console(); // Example: Write to console
});
            

Best Practices

Tip: Use the ToString("D") format specifier or other relevant formatters for complex objects when logging to ensure they are logged in a readable format.
Warning: Be mindful of excessive logging during high-traffic periods, as it can consume significant resources and impact application responsiveness.

By mastering Microsoft.Extensions.Logging, you can build more robust, maintainable, and observable .NET applications.