File logging in ASP.NET Core made easy with Serilog

Published: Monday 12 January 2026

If you want to add file logging to your ASP.NET Core application, Serilog makes it simple and flexible. In this article, we will walk through installing Serilog, configuring it, and writing log entries to a text file.

Install the required NuGet packages

First, install the following NuGet packages:

Once installed, open Program.cs and add the following configuration:

// Program.cs
builder.Host.UseSerilog((context, loggerConfiguration) =>
{
	loggerConfiguration.ReadFrom.Configuration(
		context.Configuration
	);
});

This tells Serilog to read its configuration from appsettings.json.

Configure Serilog in appsettings.json

Next, configure Serilog by adding a new Serilog section to appsettings.json.

We add a WriteTo array and configure a file sink. The OutputTemplate defines how each log entry is written. In this example, we output:

  • The timestamp in ISO 8601 format
  • The log level
  • The source context (for example, the namespace)
  • The log message
  • Any exception details

We also configure a rolling log file that creates a new file each day.

{
	"Logging": {
		"LogLevel": {
			"Default": "Information",
			"Microsoft.AspNetCore": "Warning"
		}
	},
	"Serilog": {
		"WriteTo": [{
			"Name": "File",
			"Args": {
				"OutputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}",
				"Path": "logs/log-.txt",
				"RollingInterval": "Day"
			}
		}]
	}	
}

With this appsettings.json configuration, log files are written to a logs folder. Each file is named using the current date, for example:

log-20260119.txt

We use Serilog in our Minimal APIs for complete beginners course. You'll also learn how to build a real application that incorporates clean architecture, Entity Framework Core with SQL Server, dependency injection, logging, authentication, and unit testing.

Add log entries to a Minimal API

Now that Serilog is configured, the next step is to write log entries.

Below is a simple example of a Minimal API endpoint.

// ProductsEndpoints.cs
public class ProductsEndpoints
{
	private readonly WebApplication _app;

	public ProductsEndpoints(WebApplication app)
	{
		_app = app;
	}

	public ProductsEndpoints MapProductsEndpoints()
	{
		var group = _app.MapGroup("/api/products");

		group.MapGet("/", Get);

		return this;
	}

	public async Task<IResult> Get()
	{
		return TypedResults.Ok(new { Success = true });
	}
}

And in Program.cs:

// Program.cs
var productsEndpoints = new ProductsEndpoints(app);
productsEndpoints.MapProductsEndpoints();

This creates a product endpoint group mapped to /api/products and exposes a GET endpoint.

Inject ILogger and write a log entry

To write logs, inject ILogger<T> into your endpoint method. In this example, we also accept a type parameter from the request.

// ProductsEndpoints.cs
namespace RoundTheCode.Logging;

public class ProductsEndpoints
{
	...

	public async Task<IResult> Get(
		string type,
		ILogger<ProductsEndpoints> logger
	)
	{
		logger.LogDebug(
			"Running the Get method (Type: {0})",
			type
		);

		return TypedResults.Ok(new { Success = true });
	}
}

Why are only Microsoft logs written?

When you first run the application, you may notice that only logs from Microsoft namespaces are written to the file, for example:

[2026-01-10 13:53:13] [INF] [Microsoft.Hosting.Lifetime] Application started. Press Ctrl+C to shut down.

This will happen if you have Logging configured with its default settings in appsettings.json:

{
	"Logging": {
		"LogLevel": {
			"Default": "Information",
			"Microsoft.AspNetCore": "Warning"
		}
	},
}

Configure MinimumLevel

To include logs from your own application, you can configure MinimumLevel in Serilog.

In this appsettings.json example:

  • We've removed Logging as we are now using Serilog > MinimumLevel for the configuration
  • The default level is set to Error
  • The RoundTheCode.Logging namespace is overridden to Debug
{
	"Serilog": {
		"MinimumLevel": {
			"Default": "Error",
			"Override": {
				"RoundTheCode.Logging": "Debug"
			}
		},
		"WriteTo": [
			...
		]
	}
}

Serilog supports the following severity levels, from least to most severe:

  • Verbose
  • Debug
  • Information
  • Warning
  • Error
  • Fatal

When you set a minimum level, Serilog logs entries at that level and anything above it.

Final result

When you run the application again, Microsoft information framework logs are filtered out, and your own log entry is written instead:

[2026-01-10 13:54:00] [INF] [RoundTheCode.Logging.ProductsEndpoints] Running the Get method (Type: Products)

Watch the video

Watch the video where we show you how to install Serilog into an ASP.NET Core Web API, configure it, and write log entries to a text file.

Final thoughts

Serilog is easy to install, simple to configure, and extremely powerful. If you want to write log entries to a text file in your ASP.NET Core application, Serilog is an excellent choice.