Serilog
Structured event logging. Github: Getting Started · serilog/serilog Wiki (github.com)
dotnet add package serilog
dotnet add package serilog.sinks.consolePretty print to console.
dotnet add package serilog.sinks.fileLog to file.
Other Sinks Available: https://github.com/serilog/serilog/wiki/Provided-Sinks
creating loggers
Serilog.Core.Logger
Serilog.Ilogger
Serilog.Log
create root logger
Create this on application startup and then use it across classes:
using var log = new LoggerConfiguration()
.MinimumLevel.Debug() // The minimum log level. If not specified, Information is used.
.WriteTo.Console( // The WriteTo object configures sinks.
AnsiConsoleTheme.Code, // 256-color VS Code inspired theme.
// Also: ConsoleTheme.None, SystemConsoleTheme.Literate (default), SystemConsoleTheme.Grayscale
outputTemplate: "[{Level:u3}] [{Timestamp: HH:mm:ss}] {Message}{Newline}{Exception}")
.WriteTo.File("path",
new CompactJsonFormatter(), // Emit output as JSON instead of plaintext. See also: https://github.com/serilog/serilog/wiki/Formatting-Output#formatting-json
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: n, // Override the default (1GB) file size limit.
retainedFileCountLimit: n, // Override the default (31) number of log files to keep.
rollOnFileSizeLimit: true // Force roll over if the file size limit is met.
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"),
Message:lj // Output (l)iterals as is, the rest in (j)son.
Level:u3 // Output the level names as 3-character (u)ppercase. Or: lo(w)ercase.
Properties:j // Output additional context information as (j)son (or omit (j) for plain text).
restrictedToMinimumLevel: LogEventLevel.Information) // Override the minimum debug level. Must be higher than the Logger's level.
.CreateLogger();
Set the Global, Statically-Accessible Logger
This is not required.
Log.Logger = log;
Use the Logger
log.Information("Log entry");
Log Structured Data
var count = 456;
Log.Information("Retrieved {Count} records", count);
Output: { "Count": 456 }
var fruit = new[] { "Apple", "Pear", "Orange" };
Log.Information("In my bowl I have {Fruit}", fruit);
Output: { "Fruit": ["Apple", "Pear", "Orange"] }
destructuring
Use @
operator to pull values out of structured data:
var sensorInput = new { Latitude = 25, Longitude = 134 };
Log.Information("Processing {@SensorInput}", sensorInput);
// Extract only a subset of properties from a complex object:
Log.Logger = new LoggerConfiguration()
.Destructure.ByTransforming<HttpRequest>(
r => new { RawUrl = r.RawUrl, Method = r.Method })
.WriteTo...
forcing stringification
Use $
operator to convert the property value to a string before any other processing takes place:
var unknown = new[] { 1, 2, 3 }
Log.Information("Received {$Data}", unknown); // Output: "System.Int32[]"
output templates
Log output templates are used by text-based sinks like console and file.
They are a superset of .NET format strings. Any valid string.Format()
is accepted.
Built-in properties:{Property:format specifier}
Exception
- Full exception message and stack trace, multiple lines. Empty if no exception for the event.
Level
- The log event level as the full level name.:u
letter level, uppercase.:w
letter level, lowercase.
Message
:l
- Disables quoting of strings.:j
- Use JSON-style rendering for any structured data.NewLine
- System.Environment.NewLine
Properties
- All other event properties that do not appear elsewhere in the output.
:j
Timestamp
- As a DateTimeOffset
Tips
- Escape
{
with another{
- Name properties (like
Count
above) with PascalCase. - Log messages in fragments; avoid periods at end when possible.
- Don’t:
Log.Information("The time is " + DateTime.Now);
This degrades performance and consumes cache memory.
- Do:
Log.Information("The time is {Now}", DateTime.Now);
shutdown
log.CloseAndFlush();
AppSettings Configuration
XML config file based configurations.
installation
dotnet add package serilog.settings.appsettings
reading config file
Log.Logger = new LoggerConfiguration()
.ReadFrom.AppSettings()
// … Other configuration
.CreateLogger();
see also
Enrichers
Enrichers enrich a log event with properties of (like attaching a thread ID).
For Web Apps (ASP.NET)
logging levels
Verbose
- The noisiest; rarely used in production applicationsDebug
- detailed information typically of use only when diagnosing problemsInformation
- confirmation that things are working as expectedWarning
- an indication that something unexpected happened, or indicative of some problem in the near future (e.g.: “disk space low”); the software is still working as expectedError
- due to a more serious problem, the software has not been able to perform some functionFatal
- a serious error indicating that the software itself may be unable to continue running
markers
[>] Start
[·] Debug
[-] Info
[] Notice (WARN)
[#] Error
[!] Critical
[<] End
[?] Input