Logging in .NET Core: Built-in Logging vs Serilog with Full Implementation Guide

Logging in .NET Core: Built-in Logging vs Serilog

Logging in .NET Core: Built-in Logging vs Serilog

Introduction

Logging is an essential part of application development and maintenance. In .NET Core (and .NET 5/6/7/8), Microsoft provides a built-in logging system. However, for structured, flexible, and production-grade logging, libraries like Serilog are often preferred.

Built-in Logging Overview

.NET Core uses Microsoft.Extensions.Logging, which provides an abstraction over different logging providers like:

  • Console
  • Debug
  • EventSource
  • EventLog (Windows only)
  • Azure App Insights (via extensions)

Pros:

  • Simple and built-in
  • Integrated with Dependency Injection (DI)

Cons:

  • Limited formatting
  • No structured logging support

What is Serilog?

Serilog is a structured logging library for .NET. It logs events using key-value pairs, making logs easier to read, filter, and analyze.

Pros:

  • Structured logging
  • Extensive sink support (Console, File, SQL, Elasticsearch, Seq)
  • Custom enrichment and formatting
  • Async logging support

Cons:

  • Requires additional packages and setup

Comparison: Built-in Logging vs Serilog

Feature Built-in Logging Serilog
Structured loggingNoYes
FormattingBasicCustomizable
File loggingNoYes
Async supportNoYes
Sink supportLimitedExtensive
DI IntegrationYesYes

Example: Built-in Logging Setup

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

// Configure built-in logging
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", (ILogger<Program> logger) =>
{
    logger.LogInformation("Request received at /");
    return "Hello World!";
});

app.Run();

Example: Serilog with Console & File

Step 1: Install NuGet Packages

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File

Step 2: Configure Program.cs

using Serilog;

var builder = WebApplication.CreateBuilder(args);

// Setup Serilog
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day)
    .Enrich.FromLogContext()
    .MinimumLevel.Debug()
    .CreateLogger();

builder.Host.UseSerilog();

var app = builder.Build();

app.MapGet("/", (ILogger<Program> logger) =>
{
    logger.LogInformation("Handled GET /");
    return "Hello from Serilog!";
});

app.Run();

Optional: Serilog with appsettings.json

Step 1: Add Configuration Package

dotnet add package Serilog.Settings.Configuration

Step 2: Add Configuration to appsettings.json

"Serilog": {
  "MinimumLevel": "Debug",
  "WriteTo": [
    { "Name": "Console" },
    {
      "Name": "File",
      "Args": {
        "path": "Logs/log-.txt",
        "rollingInterval": "Day"
      }
    }
  ],
  "Enrich": [ "FromLogContext" ]
}

Step 3: Modify Program.cs

var builder = WebApplication.CreateBuilder(args);

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .CreateLogger();

builder.Host.UseSerilog();
Tip: Combine both appsettings.json and code-based configuration for more flexibility in dev vs prod environments.

Conclusion

For simple applications, .NET Core's built-in logging is more than enough. But for complex applications that require structured, filterable, and rich logs, Serilog provides a production-ready solution with easy extensibility and integration.

Choose your logging strategy based on project size, performance needs, and maintainability goals.

Comments

Popular posts from this blog

Debouncing & Throttling in RxJS: Optimizing API Calls and User Interactions

Promises in Angular

Comprehensive Guide to C# and .NET Core OOP Concepts and Language Features