Serilog is typically configured via code though its configuration APIs, but it is quite common to specify the settings also from some sort of configuration file.
For that purpose, several Settings providers exist, that mimic the code-based API and allow supplying values from external sources :
- Serilog.Settings.AppSettings allows to read configuration from the
<appSettings>
section of anApp.config
orWeb.config
file, - Serilog.Settings.Configuration relies on Microsoft.Logging.Configuration to read settings from sources in JSON, XML or anything that can be plugged in the ConfigurationProvider APIs
To use Serilog.Settings.AppSettings, install the Nuget package, and configure you logger like :
new LoggerConfiguration().ReadFrom.AppSettings()
// snip ...
.CreateLogger();
To use Serilog.Settings.Configuration, install the Nuget package, and configure you logger like :
var config = new ConfigurationBuilder()
.AddJsonFile(fileName, optional: false) // or possibly other sources
.Build();
new LoggerConfiguration().ReadFrom.Configuration(config)
// snip ...
.CreateLogger();
You will find below some snippets of common configuration code in C# with the equivalent settings in JSON and XML.
Loading an empty config file behaves the same as the default CreateLogger()
. Minimum Level is Information.
- in JSON (ex :
101-Empty-EmptySection.json
)
{
"Serilog": {}
}
- in XML (ex :
101-Empty-EmptySection.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
</appSettings>
</configuration>
Global Minimum level can be defined.
- in C# (ex :
110-MinimumLevel.csx
)
LoggerConfiguration
.MinimumLevel.Warning();
- in JSON (ex :
110-MinimumLevel.json
)
{
"Serilog": {
"MinimumLevel": "Warning"
}
}
- in XML (ex :
110-MinimumLevel.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:minimum-level" value="Warning" />
</appSettings>
</configuration>
You can configure usage of a given Sink by specifying the name of the method or extension method that you would usually use after WriteTo.*
.
You may need to explicitly add a using
directive to look for extension methods in a separate assembly or Nuget package.
- in C# (ex :
120-WriteToWithNoParams.csx
)
#r ".\TestDummies.dll"
using System;
using TestDummies;
LoggerConfiguration
.WriteTo.Dummy();
- in JSON (ex :
120-WriteToWithNoParams.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [ "Dummy" ]
}
}
- in XML (ex :
120-WriteToWithNoParams.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:Dummy" />
</appSettings>
</configuration>
Parameters of type LogEventLevel
such as restrictedToMinimumLevel
can be provided from the level's name.
- in C# (ex :
125-WriteToRestrictedToMinimumLevel.csx
)
#r ".\TestDummies.dll"
using Serilog.Events;
using TestDummies;
LoggerConfiguration
.WriteTo.Dummy(restrictedToMinimumLevel: LogEventLevel.Error);
- in JSON (ex :
125-WriteToRestrictedToMinimumLevel.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "Dummy",
"Args": {
"restrictedToMinimumLevel": "Error"
}
}
]
}
}
- in XML (ex :
125-WriteToRestrictedToMinimumLevel.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:Dummy.restrictedToMinimumLevel" value="Error" />
</appSettings>
</configuration>
Simple types that are convertible from string can be passed. Empty string can be provided to specify null for nullable parameters. Parameters with a default value can be omitted.
- in C# (ex :
128-WriteToWithSimpleParams.csx
)
#r ".\TestDummies.dll"
using TestDummies;
LoggerConfiguration
.WriteTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null);
- in JSON (ex :
128-WriteToWithSimpleParams.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "Dummy",
"Args": {
"stringParam": "A string param",
"intParam": 666,
"nullableIntParam": ""
}
}
]
}
}
- in XML (ex :
128-WriteToWithSimpleParams.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:Dummy.stringParam" value="A string param" />
<add key="serilog:write-to:Dummy.intParam" value="666" />
<add key="serilog:write-to:Dummy.nullableIntParam" value="" />
</appSettings>
</configuration>
Log events can be enriched with arbitrary properties.
- in C# (ex :
130-EnrichWithProperty.csx
)
LoggerConfiguration
.Enrich.WithProperty("AppName", "MyApp")
.Enrich.WithProperty("ServerName", "MyServer");
- in JSON (ex :
130-EnrichWithProperty.json
)
{
"Serilog": {
"Properties": {
"AppName": "MyApp",
"ServerName": "MyServer"
}
}
}
- in XML (ex :
130-EnrichWithProperty.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:enrich:with-property:AppName" value="MyApp" />
<add key="serilog:enrich:with-property:ServerName" value="MyServer" />
</appSettings>
</configuration>
The following scenarios are also supported.
Minimum level can be overriden (up or down) for specific SourceContext
s.
- in C# (ex :
210-MinimumLevelOverrides.csx
)
using Serilog.Events;
LoggerConfiguration
.MinimumLevel.Verbose()
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
.MinimumLevel.Override("Microsoft.Extensions", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Debug)
;
- in JSON (ex :
210-MinimumLevelOverrides.json
)
{
"Serilog": {
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Error",
"Microsoft.Extensions": "Information",
"System": "Debug"
}
}
}
}
- in XML (ex :
210-MinimumLevelOverrides.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:minimum-level" value="Verbose" />
<add key="serilog:minimum-level:override:Microsoft" value="Error" />
<add key="serilog:minimum-level:override:Microsoft.Extensions" value="Information" />
<add key="serilog:minimum-level:override:System" value="Debug" />
</appSettings>
</configuration>
Some sinks provide Audit functionality via the configuration method .AuditTo.MySink()
. This is also supported via configuration.
- in C# (ex :
221-AuditToWithSimpleParams.csx
)
#r ".\TestDummies.dll"
using TestDummies;
LoggerConfiguration
.AuditTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null);
- in JSON (ex :
221-AuditToWithSimpleParams.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"AuditTo": [
{
"Name": "Dummy",
"Args": {
"stringParam": "A string param",
"intParam": 666,
"nullableIntParam": ""
}
}
]
}
}
- in XML (ex :
221-AuditToWithSimpleParams.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:audit-to:Dummy.stringParam" value="A string param" />
<add key="serilog:audit-to:Dummy.intParam" value="666" />
<add key="serilog:audit-to:Dummy.nullableIntParam" value="" />
</appSettings>
</configuration>
Some sinks such as the Seq sink accept a LoggingLevelSwitch
that can be remote-controlled. In those case, the same LoggingLevelSwitch
instance that is used to control the global minimum level must be used.
The reference to the switch is noted with the symbol $
.
- in C# (ex :
222-LoggingLevelSwitch.csx
)
#r ".\TestDummies.dll"
using Serilog.Core;
using Serilog.Events;
using TestDummies;
var mySwitch = new LoggingLevelSwitch(LogEventLevel.Warning);
LoggerConfiguration
.MinimumLevel.ControlledBy(mySwitch)
.WriteTo.DummyWithLevelSwitch(controlLevelSwitch: mySwitch);
- in JSON (ex :
222-LoggingLevelSwitch.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"LevelSwitches": { "$mySwitch": "Warning" },
"MinimumLevel": {
"ControlledBy": "$mySwitch"
},
"WriteTo": [
{
"Name": "DummyWithLevelSwitch",
"Args": {
"controlLevelSwitch": "$mySwitch"
}
}
]
}
}
- in XML (ex :
222-LoggingLevelSwitch.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:level-switch:$mySwitch" value="Warning" />
<add key="serilog:minimum-level:controlled-by" value="$mySwitch" />
<add key="serilog:write-to:DummyWithLevelSwitch.controlLevelSwitch" value="$mySwitch" />
</appSettings>
</configuration>
Log events can be enriched with LogContext
.
- in C# (ex :
230-EnrichFromLogContext.csx
)
LoggerConfiguration.Enrich.FromLogContext();
- in JSON (ex :
230-EnrichFromLogContext.json
)
{
"Serilog": {
"Enrich": [ "FromLogContext" ]
}
}
- in XML (ex :
230-EnrichFromLogContext.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:enrich:FromLogContext" value="" />
</appSettings>
</configuration>
Specific Destructuring rules can be specified.
- in C# (ex :
235-Destructure.csx
)
#r ".\TestDummies.dll"
using TestDummies;
using TestDummies.Policies;
LoggerConfiguration
.Destructure.ToMaximumDepth(maximumDestructuringDepth: 3)
.Destructure.ToMaximumStringLength(maximumStringLength: 3)
.Destructure.ToMaximumCollectionCount(maximumCollectionCount: 3)
.Destructure.AsScalar(typeof(System.Version))
.Destructure.With(new CustomPolicy());
- in JSON (ex :
235-Destructure.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"Destructure": [
{
"Name": "ToMaximumDepth",
"Args": { "maximumDestructuringDepth": 3 }
},
{
"Name": "ToMaximumStringLength",
"Args": { "maximumStringLength": 3 }
},
{
"Name": "ToMaximumCollectionCount",
"Args": { "maximumCollectionCount": 3 }
},
{
"Name": "AsScalar",
"Args": { "scalarType": "System.Version" }
},
{
"Name": "With",
"Args": { "policy": "TestDummies.Policies.CustomPolicy, TestDummies" }
}
]
}
}
- in XML (ex :
235-Destructure.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:destructure:ToMaximumDepth.maximumDestructuringDepth" value="3" />
<add key="serilog:destructure:ToMaximumStringLength.maximumStringLength" value="3" />
<add key="serilog:destructure:ToMaximumCollectionCount.maximumCollectionCount" value="3" />
<add key="serilog:destructure:AsScalar.scalarType" value="System.Version" />
<add key="serilog:destructure:With.policy" value="TestDummies.Policies.CustomPolicy, TestDummies" />
</appSettings>
</configuration>
Filtering can be specified using filter expressions thanks to the package Serilog.Filters.Expressions.
- in C# (ex :
240-FilterExpressions.csx
)
#r ".\Serilog.Filters.Expressions.dll"
LoggerConfiguration
.Filter.ByExcluding("filter = 'exclude'");
- in JSON (ex :
240-FilterExpressions.json
)
{
"Serilog": {
"Using": [ "Serilog.Filters.Expressions" ],
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "filter = 'exclude'"
}
}
]
}
}
- in XML (ex :
240-FilterExpressions.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:Serilog.Filters.Expressions" value="Serilog.Filters.Expressions" />
<add key="serilog:filter:ByExcluding.expression" value="filter = 'exclude'" />
</appSettings>
</configuration>
When conditional configuration is needed depending on the sinks, sub-loggers can be used. More about sub-loggers
- in C# (ex :
250-SubLoggers.csx
)
#r ".\TestDummies.dll"
using TestDummies;
LoggerConfiguration
.WriteTo.Logger(lc => lc
.Enrich.WithProperty("Prop1", "PropValue1")
.WriteTo.DummyConsole()
)
.WriteTo.Logger(lc => lc
.Enrich.WithProperty("Prop2", "PropValue2")
.WriteTo.Dummy()
);
- in JSON (ex :
250-SubLoggers.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo:SubLogger1": {
"Name": "Logger",
"Args": {
"configureLogger": {
"Properties": {
"Prop1": "PropValue1"
},
"WriteTo": [ "DummyConsole" ]
}
}
},
"WriteTo:SubLogger2": {
"Name": "Logger",
"Args": {
"configureLogger": {
"Properties": {
"Prop2": "PropValue2"
},
"WriteTo": [ "Dummy" ]
}
}
}
}
}
Below are the general rules for setting values.
Settings providers will discover extension methods for configuration. Remember to add using
directives if those extension methods leave in an assembly other than Serilog.
Extension methods to the following types are supported :
Type | C# API | xml prefix | json section |
---|---|---|---|
LoggerSinkConfiguration |
config.WriteTo.* |
serilog:write-to: |
WriteTo |
LoggerAuditSinkConfiguration |
config.AuditTo.* |
serilog:audit-to: |
AuditTo |
LoggerEnrichmentConfiguration |
config.Enrich.* |
serilog:enrich: |
Enrich |
LoggerFilterConfiguration |
config.Filter.* |
serilog:filter: |
Filter |
- in C# (ex :
310-MethodDiscovery.csx
)
#r ".\TestDummies.dll"
using Serilog.Events;
using TestDummies;
LoggerConfiguration
.Filter.ByExcludingLevel(LogEventLevel.Warning)
.Enrich.WithDummyUserName("UserExtraParam")
.AuditTo.Dummy(stringParam: "A string param", intParam: 666)
.WriteTo.Dummy()
;
- in JSON (ex :
310-MethodDiscovery.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"Filter": [
{
"Name": "ByExcludingLevel",
"Args": {
"excludedLevel": "Warning"
}
}
],
"Enrich": [
{
"Name": "WithDummyUserName",
"Args": {
"extraParam": "UserExtraParam"
}
}
],
"AuditTo": [
{
"Name": "Dummy",
"Args": {
"stringParam": "A string param",
"intParam": 666
}
}
],
"WriteTo": [ "Dummy" ]
}
}
- in XML (ex :
310-MethodDiscovery.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:filter:ByExcludingLevel.excludedLevel" value="Warning" />
<add key="serilog:enrich:WithDummyUserName.extraParam" value="UserExtraParam" />
<add key="serilog:audit-to:Dummy.stringParam" value="A string param" />
<add key="serilog:audit-to:Dummy.intParam" value="666" />
<add key="serilog:write-to:Dummy" value="" />
</appSettings>
</configuration>
Values for settings can be simple value types (string
, int
, bool
etc), nullable versions of the previous. Enum
s can also be parsed by name. Some specific types like Uri
and TimeSpan
are also supported.
- in C# (ex :
320-SettingsValueConversions.csx
)
#r ".\TestDummies.dll"
using System;
using TestDummies;
LoggerConfiguration
.WriteTo.DummyWithManyParams(
enumParam: MyEnum.Qux,
timespanParam: new TimeSpan(2, 3, 4, 5),
uriParam: new Uri("https://www.serilog.net"));
- in JSON (ex :
320-SettingsValueConversions.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "DummyWithManyParams",
"Args": {
"enumParam": "Qux",
"timespanParam": "2.03:04:05",
"uriParam": "https://www.serilog.net"
}
}
]
}
}
- in XML (ex :
320-SettingsValueConversions.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:DummyWithManyParams.enumParam" value="Qux" />
<add key="serilog:write-to:DummyWithManyParams.timespanParam" value="2.03:04:05" />
<add key="serilog:write-to:DummyWithManyParams.uriParam" value="https://www.serilog.net" />
</appSettings>
</configuration>
Arrays or complex type can also be passed to configuration methods.
- in C# (ex :
321-ComplexValues.csx
)
#r ".\TestDummies.dll"
using TestDummies;
LoggerConfiguration
.WriteTo.DummyWithComplexParams(
poco: new Poco()
{
StringProperty = "myString",
IntProperty = 42,
Nested = new SubPoco()
{
SubProperty = "Sub"
}
},
intArray: new[] { 2, 4, 6 },
stringArray: new[] { "one", "two", "three" },
objArray: new SubPoco[]
{
new SubPoco()
{
SubProperty = "Sub1"
},
new SubPoco()
{
SubProperty = "Sub2"
}
}
);
- in JSON (ex :
321-ComplexValues.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "DummyWithComplexParams",
"Args": {
"poco": {
"stringProperty": "myString",
"intProperty": 42,
"nested": {
"subProperty": "Sub"
}
},
"intArray": [ 2, 4, 6 ],
"stringArray": [ "one", "two", "three" ],
"objArray": [
{ "subProperty": "Sub1" },
{ "subProperty": "Sub2" }
]
}
}
]
}
}
For parameters whose type is an interface
or an abstract class
, the full type name of an implementation can be provided. If the type is not in the Serilog
assembly, remember to include using
directives.
- in C# (ex :
331-ImplementationDefaultConstructor.csx
)
#r ".\TestDummies.dll"
using System;
using Serilog.Formatting.Json;
using TestDummies;
using TestDummies.Console;
LoggerConfiguration
.WriteTo.DummyWithFormatter(formatter: new JsonFormatter())
.WriteTo.DummyConsole(theme: new CustomConsoleTheme());
- in JSON (ex :
331-ImplementationDefaultConstructor.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "DummyWithFormatter",
"Args": {
"formatter": "Serilog.Formatting.Json.JsonFormatter"
}
},
{
"Name": "DummyConsole",
"Args": {
"theme": "TestDummies.Console.CustomConsoleTheme, TestDummies"
}
}
]
}
}
- in XML (ex :
331-ImplementationDefaultConstructor.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:DummyWithFormatter.formatter" value="Serilog.Formatting.Json.JsonFormatter" />
<add key="serilog:write-to:DummyConsole.theme" value="TestDummies.Console.CustomConsoleTheme, TestDummies" />
</appSettings>
</configuration>
For parameters whose type is an interface
or an abstract class
, you can reference a static property that exposes an instance of that interface. Use the full containing type name followed by ::
and the public static
property name.
- in C# (ex :
332-ImplementationViaStaticProperty.csx
)
#r ".\TestDummies.dll"
#r ".\Serilog.Settings.Comparison.Tests.dll"
using System;
using Serilog.Formatting.Json;
using TestDummies;
using TestDummies.Console;
using TestDummies.Console.Themes;
using Serilog.SettingsComparisonTests.Support.Formatting;
LoggerConfiguration
.WriteTo.DummyWithFormatter(formatter: CustomFormatters.Formatter)
.WriteTo.DummyConsole(theme: ConsoleThemes.Theme1);
- in JSON (ex :
332-ImplementationViaStaticProperty.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "DummyWithFormatter",
"Args": {
"formatter": "Serilog.SettingsComparisonTests.Support.Formatting.CustomFormatters::Formatter, Serilog.Settings.Comparison.Tests"
}
},
{
"Name": "DummyConsole",
"Args": {
"theme": "TestDummies.Console.Themes.ConsoleThemes::Theme1, TestDummies"
}
}
]
}
}
- in XML (ex :
332-ImplementationViaStaticProperty.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:DummyWithFormatter.formatter" value="Serilog.SettingsComparisonTests.Support.Formatting.CustomFormatters::Formatter, Serilog.Settings.Comparison.Tests" />
<add key="serilog:write-to:DummyConsole.theme" value="TestDummies.Console.Themes.ConsoleThemes::Theme1, TestDummies" />
</appSettings>
</configuration>
Values like %ENV_VARIABLE%
are replaced by the value of the environment variable ENV_VARIABLE
.
This can be used, for instance, to provide environment-dependent property-enrichment (ex: %COMPUTERNAME%
) or paths (ex: %TEMP%).
- in C# (ex :
390-EnvironmentVariableExpansion.csx
)
#r ".\TestDummies.dll"
using System;
using TestDummies;
LoggerConfiguration
.WriteTo.Dummy(
stringParam: Environment.ExpandEnvironmentVariables("%PATH%"),
intParam: Int32.Parse(Environment.ExpandEnvironmentVariables("%NUMBER_OF_PROCESSORS%")));
- in JSON (ex :
390-EnvironmentVariableExpansion.json
)
{
"Serilog": {
"Using": [ "TestDummies" ],
"WriteTo": [
{
"Name": "Dummy",
"Args": {
"stringParam": "%PATH%",
"intParam": "%NUMBER_OF_PROCESSORS%"
}
}
]
}
}
- in XML (ex :
390-EnvironmentVariableExpansion.config
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="serilog:using:TestDummies" value="TestDummies" />
<add key="serilog:write-to:Dummy.stringParam" value="%PATH%" />
<add key="serilog:write-to:Dummy.intParam" value="%NUMBER_OF_PROCESSORS%" />
</appSettings>
</configuration>