Serilog File Logging

Overview

EasyAdminBlazor ships with database logging (viewable on the admin “Error Log” page). For production troubleshooting, file logging is often needed: write logs to the server disk with daily/size-based rotation so they can be inspected and archived directly. Serilog is the recommended way — a few lines of configuration, and it can coexist with the framework’s built-in database logger.

Installation

Add the NuGet packages to your project (pick the latest stable versions matching your .NET version):

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

Quick Start

Add the following in Program.cs before building the builder:

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((ctx, cfg) => cfg
    .MinimumLevel.Information()
    .WriteTo.File("logs/log-.log",
        rollingInterval: RollingInterval.Day,        // rotate daily
        retainedFileCountLimit: 30,                  // keep at most 30 files
        fileSizeLimitBytes: 20 * 1024 * 1024,        // max 20MB per file
        rollOnFileSizeLimit: true,                   // roll to a new file when the size limit is hit
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
    , writeToProviders: true);                       // ⚠️ important: keep the framework’s built-in logger providers

builder.AddEasyAdminBlazor(...);

⚠️ writeToProviders: true is required: by default UseSerilog replaces the ASP.NET Core logging providers, so the framework’s database logger stops receiving entries (the admin “Error Log” page goes quiet). With this parameter, Serilog file logging and database logging coexist.

For production, keep the log level and paths in configuration. First install Serilog.Settings.Configuration:

dotnet add package Serilog.Settings.Configuration

Program.cs:

builder.Host.UseSerilog((ctx, cfg) => cfg.ReadFrom.Configuration(ctx.Configuration), writeToProviders: true);

appsettings.json:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "logs/log-.log",
          "rollingInterval": "Day",
          "retainedFileCountLimit": 30,
          "fileSizeLimitBytes": 20971520,
          "rollOnFileSizeLimit": true,
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}"
        }
      }
    ]
  }
}

Common Options

Option Description Example
rollingInterval Rotation interval Day / Hour / Minute / Infinite
retainedFileCountLimit Max log files to keep; older files are deleted 30
fileSizeLimitBytes Max size per file 20971520 (20MB)
rollOnFileSizeLimit Roll to a new file when the size limit is hit true
shared Allow multiple processes to write the same file (multi-instance) true
outputTemplate Per-line output format see above
MinimumLevel Minimum log level Warning (recommended for production)
MinimumLevel.Override Per-namespace level override "Microsoft": "Warning"

Coexisting with the Framework’s Database Logger

The two loggers serve different purposes:

  • Database logger (built-in): viewed on the admin “Error Log” page for in-console troubleshooting
  • File logger (Serilog): written to the server disk for direct inspection, archiving and auditing

The key to coexistence is writeToProviders: true. If you want file logging only (no database logger), remove the parameter (or set it to false); note that the admin “Error Log” page will then stop receiving entries.

Note: the framework’s database logger only records Error level and above (the admin “Error Log” page is for troubleshooting errors), so normal Information entries will not appear there; use the file log for full logging.

Multi-Instance Deployment Notes

  • By default, do not use shared: true; multiple processes writing the same file will conflict. Let each instance write to its own directory.
  • If multiple instances must share one log directory, add shared: true to the File sink and watch for file-lock and performance issues.
  • Disk space: control it with the retention policy (retainedFileCountLimit) so logs do not fill the disk.

Performance Tips

  • For high-throughput scenarios, add Serilog.Sinks.Async for asynchronous disk writes so logging does not slow down requests.
  • In production, start at Warning to avoid flooding the disk with Information entries.

Troubleshooting

  • No log file is created: check that the directory exists and is writable; check whether MinimumLevel filters out the target level.
  • The admin “Error Log” page has no new entries: UseSerilog replaced the default providers — verify writeToProviders: true is present.
  • Chinese characters garbled: Serilog writes UTF-8 by default; if you need another encoding, specify encoding.