This article shows how to implement logging in an ASP.NET Core application using Serilog and Azure as a hosting environment.
Code: https://github.com/damienbod/aspnetcore-azure-logging
Priority logging use cases
Two types of default logging use cases need to be supported in most software solutions. The application requires near real time logs which can be easily viewed and persisted logs for a period of time which can be viewed after something goes wrong. This needs to work in development and also in production. We have many other logging use cases as well, I just want to cover the basic logging requirements here.
- Real time logging development
- Real time logging production
- Persisted logging development
- Persisted logging production
In this setup, I use Azure App Insights for persisted logging on the production server. This has the problem that the logs only appear after n-minutes. A near real view is also required.
Setup
The ASP.NET Core application is deployed to an Azure App Service (Linux hosted). I like to use this as it is simple and scales good with web applications. I use Serilog to add logging to my ASP.NET Core applications and add different sinks depending on the hosted environments of the dev, test, prod etc.
The following Nuget packages are used to setup the logging in this use case.
Microsoft.Extensions.Logging.Debug
Serilog
Serilog.AspNetCore
Serilog.Settings.Configuration
Serilog.Sinks.Console
Serilog.Sinks.File
Serilog.Extensions.Logging
Serilog.Enrichers.Environment
Serilog.Enrichers.Thread
Serilog.Sinks.Async
Serilog.Sinks.ApplicationInsights
Serilog.Sinks.AzureApp
The program file of the ASP.NET Core application is used to initialize the logging. I use just one configuration for both dev and production in this example. I normally use different configurations pro hosted environment. The Serilog is setup using the CreateBootstrapLogger and the UseSerilog methods. The UseSerilog reads the sinks and logging setup from a configuration file, or files if separated per environment.
using Serilog;
using AspNetCoreAzureLogging;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.AzureApp()
.CreateBootstrapLogger();
Log.Information("Starting AspNetCoreAzureLogging application");
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}")
.ReadFrom.Configuration(context.Configuration));
// ... Add here:
// define your services and pipelines
app.Run();
}
catch (Exception ex) when (ex.GetType().Name is not "StopTheHostException" && ex.GetType().Name is not "HostAbortedException")
{
Log.Fatal(ex, "Unhandled exception");
}
finally
{
Log.Information("Shut down complete");
Log.CloseAndFlush();
}
The Serilog configuration adds the Azure and file based setup. The console or the file are used for local development, the Azure App Insights is used for the persisted logs on Azure. Depending on what services you deploy, the near real time logging is setup differently.
"Serilog": {
"Using": [ "Serilog.Sinks.AzureApp", "Serilog.Sinks.ApplicationInsights" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Debug",
"System": "Debug"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"WriteTo": [
{
"Name": "AzureApp"
},
{
"Name": "ApplicationInsights",
"Args": {
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
}
},
{
"Name": "File",
"Args": {
"path": "../_logs-uifile.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}",
"rollOnFileSizeLimit": true,
"fileSizeLimitBytes": 4194304,
"retainedFileCountLimit": 5
}
}
]
},
Logging to App Insights
App Insights need to be enabled for the Azure App Service which uses a Linux hosting plan. This can be created with it enabled, or you can use the portal to enable this.
Note: this can all be setup using IaC like terraform or whatever tools you use.

The App Insights can be opened and the exceptions or the traces can be viewed in the Logs tab.

You can use KDL to view the traces or the exceptions from the application logs.

Near real time logging App Service
Azure App Insights logs do not appear for n-minutes. Due to this, sometimes you need to enable near real time logs to debug a bug on Azure deployments. This can be done using the Azure Service Logs blade. Enable the File System logs.

The log stream can be used to view thenear real time logs view.

On a development system, I use the log files or the console to debug the application. I do not use App Insights in the development environment if this can be avoided as it adds complexity and delays in development.
Notes
This just covers the two default logging requirements which can be used for development and production. There are many other logging features which can be implemented and monitored but these two basic ones should always be supported and working in all solutions. You can also use logging solutions like Seq server or Elasticsearch, main thing is to use one.
Links
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging
https://learn.microsoft.com/en-us/azure/azure-monitor/app/ilogger
https://learn.microsoft.com/en-us/azure/azure-monitor/app/tutorial-asp-net-core
https://github.com/serilog/serilog