Serilog is a .NET library for recording structured log events. Instead of relying only on message strings, structured events retain properties that can be queried. Serilog can run as its own logging API or as a provider behind Microsoft.Extensions.Logging. Using it as a provider lets an ASP.NET Core API keep its existing ILogger calls. section 7.4.1 section 7.6
Two extension points make Serilog useful: sinks send events to destinations such as SQL Server or files; enrichers add context such as a machine name or thread ID. Each can be installed through a separate NuGet package. section 7.4.1
To store a board-game API’s logs in SQL Server:
- Install Serilog.AspNetCore for host integration and Serilog.Sinks.MSSqlServer for database output. section 7.4.2
- In Program.cs, call builder.Host.UseSerilog and configure WriteTo.MSSqlServer. The example uses the API’s existing connection string, names the table LogEvents, and enables AutoCreateSqlTable. section 7.4.3
- Set writeToProviders: true if events should also reach registered Microsoft logging providers. Without it, Serilog’s default behavior replaces those providers rather than forwarding events to them. section 7.4.3
- Run the API, call /BoardGame, then inspect LogEvents in SQL Server Management Studio. The table should contain the resulting events, including any custom event logged by the controller. section 7.4.4
builder.Logging #1
.ClearProviders()
.AddSimpleConsole()
.AddDebug()
.AddApplicationInsights(
telemetry => telemetry.ConnectionString =
builder
.Configuration["Azure:ApplicationInsights:ConnectionString"],
loggerOptions => { });
builder.Host.UseSerilog((ctx, lc) => { #2
lc.ReadFrom.Configuration(ctx.Configuration);
lc.WriteTo.MSSqlServer(
connectionString:
ctx.Configuration.GetConnectionString("DefaultConnection"),
sinkOptions: new MSSqlServerSinkOptions
{
TableName = "LogEvents",
AutoCreateSqlTable = true
});
},
writeToProviders: true);
The host configuration shows the SQL Server sink alongside the existing console, debug, and Application Insights providers. section 7.4.3
The generated table includes fields for the message, message template, level, timestamp, exception, and properties. Properties such as SourceContext and EventId initially sit in the Properties field. To give SourceContext its own SQL column, configure ColumnOptions.AdditionalColumns; in this setup, delete the existing LogEvents table before rerunning the API so it can be generated with the new column. section 7.4.3 section 7.4.5
Keep useful context with an event
Log a start time with a named template property such as "Get method started at {StartTime:HH:mm}." and pass DateTime.Now as its value. For context on every event, install the environment and thread enricher packages and configure WithMachineName() and WithThreadId(). A file sink can write those values into a daily rolling log through its output template. section 7.4.5
Logging volume is configurable: set Serilog’s minimum level and namespace overrides in its configuration, and restrict an individual sink to a higher minimum level when needed. For example, a second daily file sink can be reserved for Error and Fatal events. section 7.4.5 section 7.5.5
