Skip to content

Commit

Permalink
make '$' sign optional for minimum level / filter switch declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Komisarchik committed Nov 23, 2020
1 parent 07d7a8d commit bc533bd
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 36 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

3.2.0 (pre-release)

* #162 - LoggingFilterSwitch support
* #202 - added support to AuditTo.Logger
* #203 - added support for custom types in arrays and custom collections
* #218 - fixed an issue with `dotnet restore` with `rid` specified if referenced from `netstandard` project
* #219 - reduced search graph for configuration dlls to avoid native assets
* #221 - added support for conditional/leveled enrichers from Serilog 2.9+
* #222 - updated Microsoft.Extensions.DependencyModel
* #231 - make '$' sign optional for minimum level / filter switch declarations
* #237 - DependencyContextAssemblyFinder fix: check `serilog` at the start of the name for any dependent package
* #239 - handle NotSupportedException for .net 5.0 single file applications

Expand Down
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<TreatSpecificWarningsAsErrors />
</PropertyGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
Expand Down
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ Any changes for `Default`, `Microsoft`, `System` sources will be applied at runt

(Note: only existing sources are respected for a dynamic update. Inserting new records in `Override` section is **not** supported.)

You can also declare `LoggingLevelSwitch`-es in custom section and reference them for Sink parameters:
You can also declare `LoggingLevelSwitch`-es in custom section and reference them for sink parameters:

```json
{
"Serilog": {
"LevelSwitches": { "$controlSwitch": "Verbose" },
"LevelSwitches": { "controlSwitch": "Verbose" },
"WriteTo": [
{
"Name": "Seq",
Expand Down Expand Up @@ -205,7 +205,7 @@ This section defines a static list of key-value pairs that will enrich log event

### Filter section

This section defines filters that will be applied to log events. It is especially usefull in combination with _[Serilog.Filters.Expression](https://github.com/serilog/serilog-filters-expressions)_ package so you can write expression in text form:
This section defines filters that will be applied to log events. It is especially usefull in combination with _[Serilog.Filters.Expression](https://github.com/serilog/serilog-expressions)_ (or legacy _[Serilog.Filters.Expression](https://github.com/serilog/serilog-filters-expressions)_) package so you can write expression in text form:

```json
"Filter": [{
Expand All @@ -216,6 +216,25 @@ This section defines filters that will be applied to log events. It is especiall
}]
```

Using this package you can also declare `LoggingFilterSwitch`-es in custom section and reference them for filter parameters:

```json
{
"Serilog": {
"FilterSwitches": { "filterSwitch": "Application = 'Sample'" },
"Filter": [
{
"Name": "ControlledBy",
"Args": {
"switch": "$filterSwitch"
}
}
]
}
```

Level updates to switches are also respected for a dynamic update.

### Nested configuration sections

Some Serilog packages require a reference to a logger configuration object. The sample program in this project illustrates this with the following entry configuring the _[Serilog.Sinks.Async](https://github.com/serilog/serilog-sinks-async)_ package to wrap the _[Serilog.Sinks.File](https://github.com/serilog/serilog-sinks-file)_ package. The `configure` parameter references the File sink configuration:
Expand Down
3 changes: 2 additions & 1 deletion sample/Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Serilog;
using Serilog.Core;
using Serilog.Events;
using System.Collections.Generic;
using Serilog.Debugging;

namespace Sample
Expand All @@ -19,6 +18,8 @@ public class Program
{
public static void Main(string[] args)
{
SelfLog.Enable(Console.Error);

Thread.CurrentThread.Name = "Main thread";

var configuration = new ConfigurationBuilder()
Expand Down
2 changes: 1 addition & 1 deletion sample/Sample/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console" ],
"LevelSwitches": { "$controlSwitch": "Verbose" },
"LevelSwitches": { "controlSwitch": "Verbose" },
"FilterSwitches": { "$filterSwitch": "Application = 'Sample'" },
"MinimumLevel": {
"Default": "Debug",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="3.0.0" />
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<None Include="..\..\assets\icon.png" Pack="true" PackagePath=""/>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System.Text.RegularExpressions;

using Serilog.Configuration;
using Serilog.Core;
Expand All @@ -17,7 +18,7 @@ namespace Serilog.Settings.Configuration
{
class ConfigurationReader : IConfigurationReader
{
const string LevelSwitchNameRegex = @"^\$[A-Za-z]+[A-Za-z0-9]*$";
const string LevelSwitchNameRegex = @"^\${0,1}[A-Za-z]+[A-Za-z0-9]*$";

readonly IConfigurationSection _section;
readonly IReadOnlyCollection<Assembly> _configurationAssemblies;
Expand Down Expand Up @@ -68,7 +69,7 @@ void ProcessFilterSwitchDeclarations()
// switchName must be something like $switch to avoid ambiguities
if (!IsValidSwitchName(switchName))
{
throw new FormatException($"\"{switchName}\" is not a valid name for a Filter Switch declaration. Filter switch must be declared with a '$' sign, like \"FilterSwitches\" : {{\"$switchName\" : \"{{FilterExpression}}\"}}");
throw new FormatException($"\"{switchName}\" is not a valid name for a Filter Switch declaration. The first character of the name must be a letter or '$' sign, like \"FilterSwitches\" : {{\"$switchName\" : \"{{FilterExpression}}\"}}");
}

SetFilterSwitch(throwOnError: true);
Expand Down Expand Up @@ -118,7 +119,7 @@ void ProcessLevelSwitchDeclarations()
// switchName must be something like $switch to avoid ambiguities
if (!IsValidSwitchName(switchName))
{
throw new FormatException($"\"{switchName}\" is not a valid name for a Level Switch declaration. Level switch must be declared with a '$' sign, like \"LevelSwitches\" : {{\"$switchName\" : \"InitialLevel\"}}");
throw new FormatException($"\"{switchName}\" is not a valid name for a Level Switch declaration. The first character of the name must be a letter or '$' sign, like \"LevelSwitches\" : {{\"$switchName\" : \"InitialLevel\"}}");
}

LoggingLevelSwitch newSwitch;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,19 @@ public void AddLevelSwitch(string levelSwitchName, LoggingLevelSwitch levelSwitc
{
if (levelSwitchName == null) throw new ArgumentNullException(nameof(levelSwitchName));
if (levelSwitch == null) throw new ArgumentNullException(nameof(levelSwitch));
_declaredLevelSwitches[levelSwitchName] = levelSwitch;
_declaredLevelSwitches[ToSwitchReference(levelSwitchName)] = levelSwitch;
}

public void AddFilterSwitch(string filterSwitchName, LoggingFilterSwitchProxy filterSwitch)
{
if (filterSwitchName == null) throw new ArgumentNullException(nameof(filterSwitchName));
if (filterSwitch == null) throw new ArgumentNullException(nameof(filterSwitch));
_declaredFilterSwitches[filterSwitchName] = filterSwitch;
_declaredFilterSwitches[ToSwitchReference(filterSwitchName)] = filterSwitch;
}

string ToSwitchReference(string switchName)
{
return switchName.StartsWith("$") ? switchName : $"${switchName}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,10 @@ public void SinksAreConfiguredWithStaticMember()
[Theory]
[InlineData("$switchName", true)]
[InlineData("$SwitchName", true)]
[InlineData("SwitchName", true)]
[InlineData("$switch1", true)]
[InlineData("$sw1tch0", true)]
[InlineData("sw1tch0", true)]
[InlineData("$SWITCHNAME", true)]
[InlineData("$$switchname", false)]
[InlineData("$switchname$", false)]
Expand All @@ -326,32 +328,34 @@ public void LoggingLevelSwitchNameValidityScenarios(string switchName, bool expe
public void LoggingLevelSwitchWithInvalidNameThrowsFormatException()
{
var json = @"{
""Serilog"": {
""LevelSwitches"": {""switchNameNotStartingWithDollar"" : ""Warning"" }
""Serilog"": {
""LevelSwitches"": {""1InvalidSwitchName"" : ""Warning"" }
}
}";

var ex = Assert.Throws<FormatException>(() => ConfigFromJson(json));

Assert.Contains("\"switchNameNotStartingWithDollar\"", ex.Message);
Assert.Contains("\"1InvalidSwitchName\"", ex.Message);
Assert.Contains("'$' sign", ex.Message);
Assert.Contains("\"LevelSwitches\" : {\"$switchName\" :", ex.Message);
}

[Fact]
public void LoggingFilterSwitchIsConfigured()
[Theory]
[InlineData("$mySwitch")]
[InlineData("mySwitch")]
public void LoggingFilterSwitchIsConfigured(string switchName)
{
var json = @"{
'Serilog': {
'FilterSwitches': { '$mySwitch': 'Prop = 42' },
'Filter:BySwitch': {
var json = $@"{{
'Serilog': {{
'FilterSwitches': {{ '{switchName}': 'Prop = 42' }},
'Filter:BySwitch': {{
'Name': 'ControlledBy',
'Args': {
'Args': {{
'switch': '$mySwitch'
}
}
}
}";
}}
}}
}}
}}";
LogEvent evt = null;

var log = ConfigFromJson(json)
Expand All @@ -365,17 +369,19 @@ public void LoggingFilterSwitchIsConfigured()
Assert.NotNull(evt);
}

[Fact]
public void LoggingLevelSwitchIsConfigured()
[Theory]
[InlineData("$switch1")]
[InlineData("switch1")]
public void LoggingLevelSwitchIsConfigured(string switchName)
{
var json = @"{
""Serilog"": {
""LevelSwitches"": {""$switch1"" : ""Warning"" },
""MinimumLevel"" : {
""ControlledBy"" : ""$switch1""
}
}
}";
var json = $@"{{
'Serilog': {{
'LevelSwitches': {{ '{switchName}' : 'Warning' }},
'MinimumLevel' : {{
'ControlledBy' : '$switch1'
}}
}}
}}";
LogEvent evt = null;

var log = ConfigFromJson(json)
Expand Down

0 comments on commit bc533bd

Please sign in to comment.