Skip to content

Commit 759cf76

Browse files
authored
Merge pull request #242 from skomis-mm/switchNames
make '$' sign optional for minimum level / filter switch declarations
2 parents 07d7a8d + bc533bd commit 759cf76

File tree

9 files changed

+72
-36
lines changed

9 files changed

+72
-36
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
3.2.0 (pre-release)
44

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

Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<Project>
22
<PropertyGroup>
33
<LangVersion>latest</LangVersion>
4+
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
5+
<TreatSpecificWarningsAsErrors />
46
</PropertyGroup>
57

68
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ Any changes for `Default`, `Microsoft`, `System` sources will be applied at runt
140140

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

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

145145
```json
146146
{
147147
"Serilog": {
148-
"LevelSwitches": { "$controlSwitch": "Verbose" },
148+
"LevelSwitches": { "controlSwitch": "Verbose" },
149149
"WriteTo": [
150150
{
151151
"Name": "Seq",
@@ -205,7 +205,7 @@ This section defines a static list of key-value pairs that will enrich log event
205205

206206
### Filter section
207207

208-
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:
208+
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:
209209

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

219+
Using this package you can also declare `LoggingFilterSwitch`-es in custom section and reference them for filter parameters:
220+
221+
```json
222+
{
223+
"Serilog": {
224+
"FilterSwitches": { "filterSwitch": "Application = 'Sample'" },
225+
"Filter": [
226+
{
227+
"Name": "ControlledBy",
228+
"Args": {
229+
"switch": "$filterSwitch"
230+
}
231+
}
232+
]
233+
}
234+
```
235+
236+
Level updates to switches are also respected for a dynamic update.
237+
219238
### Nested configuration sections
220239

221240
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:

sample/Sample/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using Serilog;
1111
using Serilog.Core;
1212
using Serilog.Events;
13-
using System.Collections.Generic;
1413
using Serilog.Debugging;
1514

1615
namespace Sample
@@ -19,6 +18,8 @@ public class Program
1918
{
2019
public static void Main(string[] args)
2120
{
21+
SelfLog.Enable(Console.Error);
22+
2223
Thread.CurrentThread.Name = "Main thread";
2324

2425
var configuration = new ConfigurationBuilder()

sample/Sample/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"Serilog": {
33
"Using": [ "Serilog.Sinks.Console" ],
4-
"LevelSwitches": { "$controlSwitch": "Verbose" },
4+
"LevelSwitches": { "controlSwitch": "Verbose" },
55
"FilterSwitches": { "$filterSwitch": "Application = 'Sample'" },
66
"MinimumLevel": {
77
"Default": "Debug",

src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<ItemGroup>
3232
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
3333
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="3.0.0" />
34-
<PackageReference Include="Serilog" Version="2.9.0" />
34+
<PackageReference Include="Serilog" Version="2.10.0" />
3535
<None Include="..\..\assets\icon.png" Pack="true" PackagePath=""/>
3636
</ItemGroup>
3737

src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
using System.Linq;
44
using System.Reflection;
55
using System.Runtime.CompilerServices;
6+
using System.Text.RegularExpressions;
7+
68
using Microsoft.Extensions.Configuration;
79
using Microsoft.Extensions.Primitives;
8-
using System.Text.RegularExpressions;
910

1011
using Serilog.Configuration;
1112
using Serilog.Core;
@@ -17,7 +18,7 @@ namespace Serilog.Settings.Configuration
1718
{
1819
class ConfigurationReader : IConfigurationReader
1920
{
20-
const string LevelSwitchNameRegex = @"^\$[A-Za-z]+[A-Za-z0-9]*$";
21+
const string LevelSwitchNameRegex = @"^\${0,1}[A-Za-z]+[A-Za-z0-9]*$";
2122

2223
readonly IConfigurationSection _section;
2324
readonly IReadOnlyCollection<Assembly> _configurationAssemblies;
@@ -68,7 +69,7 @@ void ProcessFilterSwitchDeclarations()
6869
// switchName must be something like $switch to avoid ambiguities
6970
if (!IsValidSwitchName(switchName))
7071
{
71-
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}}\"}}");
72+
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}}\"}}");
7273
}
7374

7475
SetFilterSwitch(throwOnError: true);
@@ -118,7 +119,7 @@ void ProcessLevelSwitchDeclarations()
118119
// switchName must be something like $switch to avoid ambiguities
119120
if (!IsValidSwitchName(switchName))
120121
{
121-
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\"}}");
122+
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\"}}");
122123
}
123124

124125
LoggingLevelSwitch newSwitch;

src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,19 @@ public void AddLevelSwitch(string levelSwitchName, LoggingLevelSwitch levelSwitc
6767
{
6868
if (levelSwitchName == null) throw new ArgumentNullException(nameof(levelSwitchName));
6969
if (levelSwitch == null) throw new ArgumentNullException(nameof(levelSwitch));
70-
_declaredLevelSwitches[levelSwitchName] = levelSwitch;
70+
_declaredLevelSwitches[ToSwitchReference(levelSwitchName)] = levelSwitch;
7171
}
7272

7373
public void AddFilterSwitch(string filterSwitchName, LoggingFilterSwitchProxy filterSwitch)
7474
{
7575
if (filterSwitchName == null) throw new ArgumentNullException(nameof(filterSwitchName));
7676
if (filterSwitch == null) throw new ArgumentNullException(nameof(filterSwitch));
77-
_declaredFilterSwitches[filterSwitchName] = filterSwitch;
77+
_declaredFilterSwitches[ToSwitchReference(filterSwitchName)] = filterSwitch;
78+
}
79+
80+
string ToSwitchReference(string switchName)
81+
{
82+
return switchName.StartsWith("$") ? switchName : $"${switchName}";
7883
}
7984
}
8085
}

test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,10 @@ public void SinksAreConfiguredWithStaticMember()
305305
[Theory]
306306
[InlineData("$switchName", true)]
307307
[InlineData("$SwitchName", true)]
308+
[InlineData("SwitchName", true)]
308309
[InlineData("$switch1", true)]
309310
[InlineData("$sw1tch0", true)]
311+
[InlineData("sw1tch0", true)]
310312
[InlineData("$SWITCHNAME", true)]
311313
[InlineData("$$switchname", false)]
312314
[InlineData("$switchname$", false)]
@@ -326,32 +328,34 @@ public void LoggingLevelSwitchNameValidityScenarios(string switchName, bool expe
326328
public void LoggingLevelSwitchWithInvalidNameThrowsFormatException()
327329
{
328330
var json = @"{
329-
""Serilog"": {
330-
""LevelSwitches"": {""switchNameNotStartingWithDollar"" : ""Warning"" }
331+
""Serilog"": {
332+
""LevelSwitches"": {""1InvalidSwitchName"" : ""Warning"" }
331333
}
332334
}";
333335

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

336-
Assert.Contains("\"switchNameNotStartingWithDollar\"", ex.Message);
338+
Assert.Contains("\"1InvalidSwitchName\"", ex.Message);
337339
Assert.Contains("'$' sign", ex.Message);
338340
Assert.Contains("\"LevelSwitches\" : {\"$switchName\" :", ex.Message);
339341
}
340342

341-
[Fact]
342-
public void LoggingFilterSwitchIsConfigured()
343+
[Theory]
344+
[InlineData("$mySwitch")]
345+
[InlineData("mySwitch")]
346+
public void LoggingFilterSwitchIsConfigured(string switchName)
343347
{
344-
var json = @"{
345-
'Serilog': {
346-
'FilterSwitches': { '$mySwitch': 'Prop = 42' },
347-
'Filter:BySwitch': {
348+
var json = $@"{{
349+
'Serilog': {{
350+
'FilterSwitches': {{ '{switchName}': 'Prop = 42' }},
351+
'Filter:BySwitch': {{
348352
'Name': 'ControlledBy',
349-
'Args': {
353+
'Args': {{
350354
'switch': '$mySwitch'
351-
}
352-
}
353-
}
354-
}";
355+
}}
356+
}}
357+
}}
358+
}}";
355359
LogEvent evt = null;
356360

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

368-
[Fact]
369-
public void LoggingLevelSwitchIsConfigured()
372+
[Theory]
373+
[InlineData("$switch1")]
374+
[InlineData("switch1")]
375+
public void LoggingLevelSwitchIsConfigured(string switchName)
370376
{
371-
var json = @"{
372-
""Serilog"": {
373-
""LevelSwitches"": {""$switch1"" : ""Warning"" },
374-
""MinimumLevel"" : {
375-
""ControlledBy"" : ""$switch1""
376-
}
377-
}
378-
}";
377+
var json = $@"{{
378+
'Serilog': {{
379+
'LevelSwitches': {{ '{switchName}' : 'Warning' }},
380+
'MinimumLevel' : {{
381+
'ControlledBy' : '$switch1'
382+
}}
383+
}}
384+
}}";
379385
LogEvent evt = null;
380386

381387
var log = ConfigFromJson(json)

0 commit comments

Comments
 (0)