Skip to content
This repository was archived by the owner on Feb 27, 2022. It is now read-only.

Commit 31aa9d2

Browse files
authored
Merge pull request #35 from serilog/dev
2.1.0 Release
2 parents ca5fbe6 + c09555d commit 31aa9d2

10 files changed

+192
-13
lines changed

README.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,29 @@ The syntax is based on SQL, with added support for object structures, arrays, an
4949
| **Grouping** | `A * (B + C)` |
5050
| **Other** | `Has(A)`, `TypeOf(A)` |
5151

52-
### XML configuration
52+
### XML `<appSettings>` configuration
5353

54-
Note, the syntax below depends on features in Serilog 2.4+.
54+
Using [_Serilog.Settings.AppSettings_](https://github.com/serilog/serilog-settings-appsettings):
5555

5656
```xml
5757
<add key="serilog:using:FilterExpressions" value="Serilog.Filters.Expressions" />
5858
<add key="serilog:filter:ByExcluding.expression" value="Name = 'World'" />
5959
```
6060

61-
61+
### JSON `appSettings.json` configuration
62+
63+
Using [_Serilog.Settings.Configuration_](https://github.com/serilog/serilog-settings-configuration):
64+
65+
```json
66+
{
67+
"Serilog": {
68+
"Using": ["Serilog.Settings.Configuration"],
69+
"Filter": [
70+
{
71+
"Name": "ByExcluding",
72+
"Args": {
73+
"expression": "EndsWith(RequestPath, '/SomeEndpoint')"
74+
}
75+
}
76+
]
77+
```

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ artifacts:
99
deploy:
1010
- provider: NuGet
1111
api_key:
12-
secure: bd9z4P73oltOXudAjPehwp9iDKsPtC+HbgshOrSgoyQKr5xVK+bxJQngrDJkHdY8
12+
secure: BDDYHSR5hA/CH7pa1e0o8+yPMgT9/DrlLOOGU3uWBufLprPFrzbAKRtq14vPNTHd
1313
skip_symbols: true
1414
on:
1515
branch: /^(master|dev)$/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Enricher/@EntryIndexedValue">True</s:Boolean>
3+
<s:Boolean x:Key="/Default/UserDictionary/Words/=nblumhardt/@EntryIndexedValue">True</s:Boolean>
4+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

src/Serilog.Filters.Expressions/Filters/Expressions/Runtime/Representation.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ public static object Expose(object internalValue)
4444

4545
var sequence = internalValue as SequenceValue;
4646
if (sequence != null)
47-
return sequence.Elements.Select(Expose).ToArray();
47+
return sequence.Elements.Select(ExposeOrRepresent).ToArray();
4848

4949
var structure = internalValue as StructureValue;
5050
if (structure != null)
5151
{
52-
var r = structure.Properties.ToDictionary(p => p.Name, p => Expose(p.Value));
52+
var r = structure.Properties.ToDictionary(p => p.Name, p => ExposeOrRepresent(p.Value));
5353
if (structure.TypeTag != null)
5454
r["$type"] = structure.TypeTag;
5555
return r;
@@ -58,12 +58,23 @@ public static object Expose(object internalValue)
5858
var dictionary = internalValue as DictionaryValue;
5959
if (dictionary != null)
6060
{
61-
return dictionary.Elements.ToDictionary(p => Expose(p.Key), p => Expose(p.Value));
61+
return dictionary.Elements.ToDictionary(p => ExposeOrRepresent(p.Key), p => ExposeOrRepresent(p.Value));
6262
}
6363

6464
return internalValue;
6565
}
6666

67+
static object ExposeOrRepresent(object internalValue)
68+
{
69+
if (internalValue is Undefined)
70+
return null;
71+
72+
if (internalValue is ScalarValue sv)
73+
return Represent(sv);
74+
75+
return Expose(internalValue);
76+
}
77+
6778
public static LogEventPropertyValue Recapture(object value)
6879
{
6980
return value is LogEventPropertyValue lepv ? lepv : new ScalarValue(value);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2019 Serilog Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using Serilog.Configuration;
17+
using Serilog.Filters.Expressions;
18+
19+
namespace Serilog
20+
{
21+
/// <summary>
22+
/// Extends logger enrichment configuration with methods for filtering with expressions.
23+
/// </summary>
24+
public static class LoggerEnrichmentConfigurationExtensions
25+
{
26+
/// <summary>
27+
/// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
28+
/// </summary>
29+
/// <param name="loggerEnrichmentConfiguration">Enrichment configuration.</param>
30+
/// <param name="expression">An expression that evaluates to <c>true</c> when the supplied
31+
/// <see cref="T:Serilog.Events.LogEvent" /> should be enriched.</param>
32+
/// <param name="configureEnricher">An action that configures the wrapped enricher.</param>
33+
/// <returns>Configuration object allowing method chaining.</returns>
34+
/// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
35+
public static LoggerConfiguration When(
36+
this LoggerEnrichmentConfiguration loggerEnrichmentConfiguration,
37+
string expression,
38+
Action<LoggerEnrichmentConfiguration> configureEnricher)
39+
{
40+
if (loggerEnrichmentConfiguration == null) throw new ArgumentNullException(nameof(loggerEnrichmentConfiguration));
41+
if (expression == null) throw new ArgumentNullException(nameof(expression));
42+
if (configureEnricher == null) throw new ArgumentNullException(nameof(configureEnricher));
43+
44+
var compiled = FilterLanguage.CreateFilter(expression);
45+
return loggerEnrichmentConfiguration.When(e => true.Equals(compiled(e)), configureEnricher);
46+
}
47+
}
48+
}

src/Serilog.Filters.Expressions/LoggerFilterConfigurationExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace Serilog
66
{
77
/// <summary>
8-
/// Extends logger configuration with methods for filtering with expressions.
8+
/// Extends logger filter configuration with methods for filtering with expressions.
99
/// </summary>
1010
public static class LoggerFilterConfigurationExtensions
1111
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2019 Serilog Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using Serilog.Configuration;
17+
using Serilog.Filters.Expressions;
18+
19+
namespace Serilog
20+
{
21+
/// <summary>
22+
/// Extends logger sink configuration with methods for filtering with expressions.
23+
/// </summary>
24+
public static class LoggerSinkConfigurationExtensions
25+
{
26+
/// <summary>
27+
/// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
28+
/// </summary>
29+
/// <param name="loggerSinkConfiguration">Sink configuration.</param>
30+
/// <param name="expression">An expression that evaluates to <c>true</c> when the
31+
/// supplied <see cref="T:Serilog.Events.LogEvent" />
32+
/// should be written to the configured sink.</param>
33+
/// <param name="configureSink">An action that configures the wrapped sink.</param>
34+
/// <returns>Configuration object allowing method chaining.</returns>
35+
/// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
36+
public static LoggerConfiguration Conditional(
37+
this LoggerSinkConfiguration loggerSinkConfiguration,
38+
string expression,
39+
Action<LoggerSinkConfiguration> configureSink)
40+
{
41+
if (loggerSinkConfiguration == null) throw new ArgumentNullException(nameof(loggerSinkConfiguration));
42+
if (expression == null) throw new ArgumentNullException(nameof(expression));
43+
if (configureSink == null) throw new ArgumentNullException(nameof(configureSink));
44+
45+
var compiled = FilterLanguage.CreateFilter(expression);
46+
return loggerSinkConfiguration.Conditional(e => true.Equals(compiled(e)), configureSink);
47+
}
48+
}
49+
}

src/Serilog.Filters.Expressions/Serilog.Filters.Expressions.csproj

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
<PropertyGroup>
44
<Description>Expression-based event filtering for Serilog.</Description>
5-
<VersionPrefix>2.0.0</VersionPrefix>
5+
<VersionPrefix>2.1.0</VersionPrefix>
66
<Authors>Serilog Contributors</Authors>
7-
<TargetFrameworks>net4.5;netstandard1.5</TargetFrameworks>
7+
<TargetFrameworks>net4.5;netstandard1.5;netstandard2.0</TargetFrameworks>
88
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
99
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1010
<AssemblyName>Serilog.Filters.Expressions</AssemblyName>
@@ -17,13 +17,15 @@
1717
<PackageIconUrl>https://serilog.net/images/serilog-extension-nuget.png</PackageIconUrl>
1818
<PackageProjectUrl>https://github.com/serilog/serilog-filters-expressions</PackageProjectUrl>
1919
<PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
20+
<RepositoryUrl>https://github.com/serilog/serilog-filters-expressions</RepositoryUrl>
21+
<RepositoryType>git</RepositoryType>
2022
<DisableImplicitFrameworkReferences Condition=" '$(TargetFramework)' == 'net4.5' ">True</DisableImplicitFrameworkReferences>
2123
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.1</NetStandardImplicitPackageVersion>
2224
</PropertyGroup>
2325

2426
<ItemGroup>
25-
<PackageReference Include="Serilog" Version="2.7.1" />
26-
<PackageReference Include="Superpower" Version="2.0.0" />
27+
<PackageReference Include="Serilog" Version="2.9.0" />
28+
<PackageReference Include="Superpower" Version="2.3.0" />
2729
</ItemGroup>
2830

2931
<ItemGroup Condition=" '$(TargetFramework)' == 'net4.5' ">
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System.Linq;
2+
using Serilog.Filters.Expressions.Tests.Support;
3+
using Xunit;
4+
5+
namespace Serilog.Filters.Expressions.Tests
6+
{
7+
public class ConfigurationTests
8+
{
9+
[Fact]
10+
public void ExpressionsControlConditionalSinks()
11+
{
12+
var sink = new CollectingSink();
13+
var logger = new LoggerConfiguration()
14+
.WriteTo.Conditional("A = 1 or A = 2", wt => wt.Sink(sink))
15+
.CreateLogger();
16+
17+
foreach (var a in Enumerable.Range(0, 5))
18+
logger.Information("{A}", a);
19+
20+
Assert.Equal(2, sink.Events.Count);
21+
}
22+
23+
[Fact]
24+
public void ExpressionsControlConditionalEnrichment()
25+
{
26+
var sink = new CollectingSink();
27+
var logger = new LoggerConfiguration()
28+
.Enrich.When("A = 1 or A = 2", e => e.WithProperty("B", 1))
29+
.WriteTo.Sink(sink)
30+
.CreateLogger();
31+
32+
foreach (var a in Enumerable.Range(0, 5))
33+
logger.Information("{A}", a);
34+
35+
Assert.Equal(2, sink.Events.Count(e => e.Properties.ContainsKey("B")));
36+
}
37+
}
38+
}

test/Serilog.Filters.Expressions.Tests/FilterExpressionCompilerTests.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Serilog.Events;
1+
using System.Collections.Generic;
2+
using Serilog.Events;
23
using Serilog.Filters.Expressions.Tests.Support;
34
using System.Linq;
45
using Xunit;
@@ -150,5 +151,15 @@ static void AssertFiltering(string expression, LogEvent match, params LogEvent[]
150151
Assert.Single(sink.Events);
151152
Assert.Same(match, sink.Events.Single());
152153
}
154+
155+
[Fact]
156+
public void StructuresAreExposedAsDictionaries()
157+
{
158+
var evt = Some.InformationEvent("{@Person}", new { Name = "nblumhardt" });
159+
var expr = FilterLanguage.CreateFilter("Person");
160+
var val = expr(evt);
161+
var dict = Assert.IsType<Dictionary<string, object>>(val);
162+
Assert.Equal("nblumhardt", dict["Name"]);
163+
}
153164
}
154165
}

0 commit comments

Comments
 (0)