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

Commit

Permalink
Merge pull request #35 from serilog/dev
Browse files Browse the repository at this point in the history
2.1.0 Release
  • Loading branch information
nblumhardt authored Dec 19, 2019
2 parents ca5fbe6 + c09555d commit 31aa9d2
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 13 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,29 @@ The syntax is based on SQL, with added support for object structures, arrays, an
| **Grouping** | `A * (B + C)` |
| **Other** | `Has(A)`, `TypeOf(A)` |

### XML configuration
### XML `<appSettings>` configuration

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

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


### JSON `appSettings.json` configuration

Using [_Serilog.Settings.Configuration_](https://github.com/serilog/serilog-settings-configuration):

```json
{
"Serilog": {
"Using": ["Serilog.Settings.Configuration"],
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "EndsWith(RequestPath, '/SomeEndpoint')"
}
}
]
```
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ artifacts:
deploy:
- provider: NuGet
api_key:
secure: bd9z4P73oltOXudAjPehwp9iDKsPtC+HbgshOrSgoyQKr5xVK+bxJQngrDJkHdY8
secure: BDDYHSR5hA/CH7pa1e0o8+yPMgT9/DrlLOOGU3uWBufLprPFrzbAKRtq14vPNTHd
skip_symbols: true
on:
branch: /^(master|dev)$/
Expand Down
4 changes: 4 additions & 0 deletions serilog-filters-expressions.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<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">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Enricher/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nblumhardt/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public static object Expose(object internalValue)

var sequence = internalValue as SequenceValue;
if (sequence != null)
return sequence.Elements.Select(Expose).ToArray();
return sequence.Elements.Select(ExposeOrRepresent).ToArray();

var structure = internalValue as StructureValue;
if (structure != null)
{
var r = structure.Properties.ToDictionary(p => p.Name, p => Expose(p.Value));
var r = structure.Properties.ToDictionary(p => p.Name, p => ExposeOrRepresent(p.Value));
if (structure.TypeTag != null)
r["$type"] = structure.TypeTag;
return r;
Expand All @@ -58,12 +58,23 @@ public static object Expose(object internalValue)
var dictionary = internalValue as DictionaryValue;
if (dictionary != null)
{
return dictionary.Elements.ToDictionary(p => Expose(p.Key), p => Expose(p.Value));
return dictionary.Elements.ToDictionary(p => ExposeOrRepresent(p.Key), p => ExposeOrRepresent(p.Value));
}

return internalValue;
}

static object ExposeOrRepresent(object internalValue)
{
if (internalValue is Undefined)
return null;

if (internalValue is ScalarValue sv)
return Represent(sv);

return Expose(internalValue);
}

public static LogEventPropertyValue Recapture(object value)
{
return value is LogEventPropertyValue lepv ? lepv : new ScalarValue(value);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2019 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using Serilog.Configuration;
using Serilog.Filters.Expressions;

namespace Serilog
{
/// <summary>
/// Extends logger enrichment configuration with methods for filtering with expressions.
/// </summary>
public static class LoggerEnrichmentConfigurationExtensions
{
/// <summary>
/// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
/// </summary>
/// <param name="loggerEnrichmentConfiguration">Enrichment configuration.</param>
/// <param name="expression">An expression that evaluates to <c>true</c> when the supplied
/// <see cref="T:Serilog.Events.LogEvent" /> should be enriched.</param>
/// <param name="configureEnricher">An action that configures the wrapped enricher.</param>
/// <returns>Configuration object allowing method chaining.</returns>
/// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
public static LoggerConfiguration When(
this LoggerEnrichmentConfiguration loggerEnrichmentConfiguration,
string expression,
Action<LoggerEnrichmentConfiguration> configureEnricher)
{
if (loggerEnrichmentConfiguration == null) throw new ArgumentNullException(nameof(loggerEnrichmentConfiguration));
if (expression == null) throw new ArgumentNullException(nameof(expression));
if (configureEnricher == null) throw new ArgumentNullException(nameof(configureEnricher));

var compiled = FilterLanguage.CreateFilter(expression);
return loggerEnrichmentConfiguration.When(e => true.Equals(compiled(e)), configureEnricher);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Serilog
{
/// <summary>
/// Extends logger configuration with methods for filtering with expressions.
/// Extends logger filter configuration with methods for filtering with expressions.
/// </summary>
public static class LoggerFilterConfigurationExtensions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2019 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using Serilog.Configuration;
using Serilog.Filters.Expressions;

namespace Serilog
{
/// <summary>
/// Extends logger sink configuration with methods for filtering with expressions.
/// </summary>
public static class LoggerSinkConfigurationExtensions
{
/// <summary>
/// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
/// </summary>
/// <param name="loggerSinkConfiguration">Sink configuration.</param>
/// <param name="expression">An expression that evaluates to <c>true</c> when the
/// supplied <see cref="T:Serilog.Events.LogEvent" />
/// should be written to the configured sink.</param>
/// <param name="configureSink">An action that configures the wrapped sink.</param>
/// <returns>Configuration object allowing method chaining.</returns>
/// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
public static LoggerConfiguration Conditional(
this LoggerSinkConfiguration loggerSinkConfiguration,
string expression,
Action<LoggerSinkConfiguration> configureSink)
{
if (loggerSinkConfiguration == null) throw new ArgumentNullException(nameof(loggerSinkConfiguration));
if (expression == null) throw new ArgumentNullException(nameof(expression));
if (configureSink == null) throw new ArgumentNullException(nameof(configureSink));

var compiled = FilterLanguage.CreateFilter(expression);
return loggerSinkConfiguration.Conditional(e => true.Equals(compiled(e)), configureSink);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

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

<ItemGroup>
<PackageReference Include="Serilog" Version="2.7.1" />
<PackageReference Include="Superpower" Version="2.0.0" />
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Superpower" Version="2.3.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net4.5' ">
Expand Down
38 changes: 38 additions & 0 deletions test/Serilog.Filters.Expressions.Tests/ConfigurationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Linq;
using Serilog.Filters.Expressions.Tests.Support;
using Xunit;

namespace Serilog.Filters.Expressions.Tests
{
public class ConfigurationTests
{
[Fact]
public void ExpressionsControlConditionalSinks()
{
var sink = new CollectingSink();
var logger = new LoggerConfiguration()
.WriteTo.Conditional("A = 1 or A = 2", wt => wt.Sink(sink))
.CreateLogger();

foreach (var a in Enumerable.Range(0, 5))
logger.Information("{A}", a);

Assert.Equal(2, sink.Events.Count);
}

[Fact]
public void ExpressionsControlConditionalEnrichment()
{
var sink = new CollectingSink();
var logger = new LoggerConfiguration()
.Enrich.When("A = 1 or A = 2", e => e.WithProperty("B", 1))
.WriteTo.Sink(sink)
.CreateLogger();

foreach (var a in Enumerable.Range(0, 5))
logger.Information("{A}", a);

Assert.Equal(2, sink.Events.Count(e => e.Properties.ContainsKey("B")));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Serilog.Events;
using System.Collections.Generic;
using Serilog.Events;
using Serilog.Filters.Expressions.Tests.Support;
using System.Linq;
using Xunit;
Expand Down Expand Up @@ -150,5 +151,15 @@ static void AssertFiltering(string expression, LogEvent match, params LogEvent[]
Assert.Single(sink.Events);
Assert.Same(match, sink.Events.Single());
}

[Fact]
public void StructuresAreExposedAsDictionaries()
{
var evt = Some.InformationEvent("{@Person}", new { Name = "nblumhardt" });
var expr = FilterLanguage.CreateFilter("Person");
var val = expr(evt);
var dict = Assert.IsType<Dictionary<string, object>>(val);
Assert.Equal("nblumhardt", dict["Name"]);
}
}
}

0 comments on commit 31aa9d2

Please sign in to comment.