serilog / serilog-expressions

An embeddable mini-language for filtering, enriching, and formatting Serilog events, ideal for use with JSON or XML configuration.
Apache License 2.0
190 stars 17 forks source link

Unable to use Regular Expression #91

Closed JORDAAAN1495 closed 1 year ago

JORDAAAN1495 commented 1 year ago

Description Attempting to make use of ByExcluding with a regular expression and receiving the below error:

System.ArgumentException : Syntax error (line 1, column 17): unexpected \, expected digit.

Stack Trace:

SerilogExpression.Compile(String expression, IFormatProvider formatProvider, NameResolver nameResolver) LoggerFilterConfigurationExtensions.ByExcluding(LoggerFilterConfiguration loggerFilterConfiguration, String expression) SerilogExpressionsTests.ShouldExcludeLogsByIpAddress(String ipAddress) line 13 RuntimeMethodHandle.InvokeMethod(Object target, Void* arguments, Signature sig, Boolean isConstructor) MethodInvoker.Invoke(Object obj, IntPtr args, BindingFlags invokeAttr)

Reproduction I've put together a unit test below which you can use to reproduce locally.

using FluentAssertions;
using Serilog;
using Serilog.Sinks.TestCorrelator;
using Xunit;

namespace SerilogExpressions.Unit.Tests;

public class SerilogExpressionsTests
{
    [Theory]
    [InlineData("100.21.33.1")]
    [InlineData("1.1.1.1")]
    public void ShouldExcludeLogsByIpAddress(string ipAddress)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo
            .TestCorrelator()
            .Enrich.WithProperty("IPAddress", ipAddress)
            .Filter.ByExcluding(@"IPAddress = ^100\.22\.(33\.([1-9]|[1-9]\d|[12]\d\d)|34\.[1-9]?\d)$")
            //.Filter.ByExcluding(@"IPAddress = /^100\.22\.(33\.([1-9]|[1-9]\d|[12]\d\d)|34\.[1-9]?\d)$/")
            .CreateLogger();

        using (TestCorrelator.CreateContext())
        {
            Exception ex = new("Test123");

            Log.Logger.Error(ex, ex.Message);

            var events = TestCorrelator.GetLogEventsFromCurrentContext().ToList();

            events.Count.Should().Be(0);
        }
    }
}

Expected behavior I'm trying to exclude logs for a given IP Address range using a regular expression.

Relevant package, tooling and runtime versions Serilog: 2.12.0 Serilog.Expressions: 3.4.1 .NET 7 I have also tried other versions of dotnet and of the packages, all with the same issue as described above.

Additional context The regular expression itself works fine in SEQ (when using in SEQ, it needs to begin and end with a forward slash).

bartelink commented 1 year ago

Not sure where you got the idea that your imagined feature is one that's intended to be supplied by this package. If it was, the classification 'bug' might begin to make sense.

This package is intended for rendering of output; the ByExcluding mechanism you are using in your snippet is part of the Serilog core.

For usage questions like this, best to post on stackoverflow.com with your example code, and more details about your goal, and tag it serilog - you'll get way more eyes on the question that way, and a quicker answer. When yo're done, come back and post a link to it here as you clsoe it.

(You should be able to use a lambda expression in the ByExcluding to filter the raw value - the entire point of structured logging is to avoid doing loose regex matches on the final text rendering. The other point to be made is that it's dubious to be doing searching of this nature within a log configuration sequence...)

nblumhardt commented 1 year ago

@"IsMatch(IPAddress, '^100\.22\.(33\.([1-9]|[1-9]\d|[12]\d\d)|34\.[1-9]?\d)$')" (or something similar using the IsMatch function) should do the trick.

The Serilog.Expressions language isn't identical to the Seq query language, with regex handling being one of the differences.

The README has more details of this and other supported operators.

JORDAAAN1495 commented 1 year ago

Thank you both @bartelink @nblumhardt The IsMatch function works as expected, many thanks for your help :)