From 78ee3cba620e7ba3acef6708fd6b470657f02b05 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Tue, 30 Jan 2024 10:04:18 +1000 Subject: [PATCH 1/3] Break the SerilogExpressions dependency, unify Seq.Syntax references to the shipped one --- global.json | 2 +- src/SeqCli/Apps/AppLoader.cs | 6 ++++-- src/SeqCli/Cli/Commands/IngestCommand.cs | 3 +-- src/SeqCli/Cli/Commands/PrintCommand.cs | 11 ++++++++++- src/SeqCli/Output/OutputFormatter.cs | 2 +- src/SeqCli/SeqCli.csproj | 1 - src/SeqCli/Syntax/SeqCliNameResolver.cs | 20 ++++++++++++++++++++ src/SeqCli/Syntax/SeqSyntax.cs | 21 ++------------------- 8 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 src/SeqCli/Syntax/SeqCliNameResolver.cs diff --git a/global.json b/global.json index f2068dc8..f3365c41 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.101" + "version": "8.0.100" } } \ No newline at end of file diff --git a/src/SeqCli/Apps/AppLoader.cs b/src/SeqCli/Apps/AppLoader.cs index 0027a16b..90872ef2 100644 --- a/src/SeqCli/Apps/AppLoader.cs +++ b/src/SeqCli/Apps/AppLoader.cs @@ -19,6 +19,7 @@ using System.Linq; using System.Reflection; using Seq.Apps; +using Seq.Syntax.Expressions; using Serilog; namespace SeqCli.Apps; @@ -30,10 +31,11 @@ class AppLoader : IDisposable // These are used for interop between the host process and the app. The // app _must_ be able to load on the unified version. readonly Assembly[] _contracts = - { + [ typeof(SeqApp).Assembly, typeof(Log).Assembly, - }; + typeof(SerilogExpression).Assembly + ]; public AppLoader(string packageBinaryPath) { diff --git a/src/SeqCli/Cli/Commands/IngestCommand.cs b/src/SeqCli/Cli/Commands/IngestCommand.cs index d591ba52..2d5ffce8 100644 --- a/src/SeqCli/Cli/Commands/IngestCommand.cs +++ b/src/SeqCli/Cli/Commands/IngestCommand.cs @@ -24,7 +24,6 @@ using Serilog; using Serilog.Core; using Serilog.Events; -using Serilog.Expressions; namespace SeqCli.Cli.Commands; @@ -95,7 +94,7 @@ protected override async Task Run() if (_filter != null) { var eval = SeqSyntax.CompileExpression(_filter); - filter = evt => ExpressionResult.IsTrue(eval(evt)); + filter = evt => Seq.Syntax.Expressions.ExpressionResult.IsTrue(eval(evt)); } var connection = _connectionFactory.Connect(_connection); diff --git a/src/SeqCli/Cli/Commands/PrintCommand.cs b/src/SeqCli/Cli/Commands/PrintCommand.cs index 698875a2..a5d24dda 100644 --- a/src/SeqCli/Cli/Commands/PrintCommand.cs +++ b/src/SeqCli/Cli/Commands/PrintCommand.cs @@ -16,6 +16,7 @@ using System.IO; using System.Threading.Tasks; using Newtonsoft.Json; +using Seq.Syntax.Expressions; using SeqCli.Cli.Features; using SeqCli.Config; using SeqCli.Ingestion; @@ -81,7 +82,15 @@ var theme applyThemeToRedirectedOutput: applyThemeToRedirectedOutput); if (_filter != null) - outputConfiguration.Filter.ByIncludingOnly(_filter); + { + if (!SerilogExpression.TryCompile(_filter, out var filter, out var error)) + { + Log.Error("The specified filter could not be compiled: {Error}", error); + return 1; + } + + outputConfiguration.Filter.ByIncludingOnly(evt => ExpressionResult.IsTrue(filter(evt))); + } await using var logger = outputConfiguration.CreateLogger(); foreach (var input in _fileInputFeature.OpenInputs()) diff --git a/src/SeqCli/Output/OutputFormatter.cs b/src/SeqCli/Output/OutputFormatter.cs index ccd14db9..cadd990d 100644 --- a/src/SeqCli/Output/OutputFormatter.cs +++ b/src/SeqCli/Output/OutputFormatter.cs @@ -1,7 +1,7 @@ using SeqCli.Ingestion; using SeqCli.Levels; using Serilog.Formatting; -using Serilog.Templates; +using Seq.Syntax.Templates; namespace SeqCli.Output; diff --git a/src/SeqCli/SeqCli.csproj b/src/SeqCli/SeqCli.csproj index b5bcd69e..1b2c5b32 100644 --- a/src/SeqCli/SeqCli.csproj +++ b/src/SeqCli/SeqCli.csproj @@ -29,7 +29,6 @@ - diff --git a/src/SeqCli/Syntax/SeqCliNameResolver.cs b/src/SeqCli/Syntax/SeqCliNameResolver.cs new file mode 100644 index 00000000..91b4abab --- /dev/null +++ b/src/SeqCli/Syntax/SeqCliNameResolver.cs @@ -0,0 +1,20 @@ +using System.Diagnostics.CodeAnalysis; +using Seq.Syntax.Expressions; + +namespace SeqCli.Syntax; + +class SeqCliNameResolver: NameResolver +{ + public override bool TryResolveBuiltInPropertyName(string alias, [MaybeNullWhen(false)] out string target) + { + switch (alias) + { + case "@l": + target = "coalesce(SeqCliOriginalLevel, @l)"; + return true; + default: + target = null; + return false; + } + } +} diff --git a/src/SeqCli/Syntax/SeqSyntax.cs b/src/SeqCli/Syntax/SeqSyntax.cs index c46642ab..3974b4ad 100644 --- a/src/SeqCli/Syntax/SeqSyntax.cs +++ b/src/SeqCli/Syntax/SeqSyntax.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using Seq.Syntax.Expressions; +using Seq.Syntax.Expressions; namespace SeqCli.Syntax; @@ -9,20 +8,4 @@ public static CompiledExpression CompileExpression(string expression) { return SerilogExpression.Compile(expression, nameResolver: new SeqCliNameResolver()); } -} - -class SeqCliNameResolver: NameResolver -{ - public override bool TryResolveBuiltInPropertyName(string alias, [MaybeNullWhen(false)] out string target) - { - switch (alias) - { - case "@l": - target = "coalesce(SeqCliOriginalLevel, @l)"; - return true; - default: - target = null; - return false; - } - } -} +} \ No newline at end of file From 4e5bfa364c40c072b330954f5b492706f562101f Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Tue, 30 Jan 2024 10:06:13 +1000 Subject: [PATCH 2/3] Revert temporaray global.json change --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index f3365c41..f2068dc8 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.100" + "version": "8.0.101" } } \ No newline at end of file From 35f8f96af93adf5a3fc58eac855b7fd39a3cbbfe Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Tue, 30 Jan 2024 10:37:19 +1000 Subject: [PATCH 3/3] Use Serilog.Expressions where knowledge of the built-in @sp property is needed --- src/SeqCli/Output/OutputFormatter.cs | 5 ++++- src/SeqCli/SeqCli.csproj | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SeqCli/Output/OutputFormatter.cs b/src/SeqCli/Output/OutputFormatter.cs index cadd990d..8d55ac4c 100644 --- a/src/SeqCli/Output/OutputFormatter.cs +++ b/src/SeqCli/Output/OutputFormatter.cs @@ -1,12 +1,15 @@ using SeqCli.Ingestion; using SeqCli.Levels; using Serilog.Formatting; -using Seq.Syntax.Templates; +using Serilog.Templates; namespace SeqCli.Output; static class OutputFormatter { + // This is the only usage of Serilog.Expressions remaining in seqcli; the upstream Seq.Syntax doesn't yet support + // the `@sp` property, because it needs to load on older Seq installs with older Serilog versions embedded in the + // app runner. Once we've updated it, we can switch this to a Seq.Syntax template. internal static readonly ITextFormatter Json = new ExpressionTemplate( $"{{ {{@t, @mt, @l: coalesce({LevelMapping.SurrogateLevelProperty}, if @l = 'Information' then undefined() else @l), @x, @sp, @tr, @ps: coalesce({TraceConstants.ParentSpanIdProperty}, @ps), @st: coalesce({TraceConstants.SpanStartTimestampProperty}, @st), ..rest()}} }}\n" ); diff --git a/src/SeqCli/SeqCli.csproj b/src/SeqCli/SeqCli.csproj index 1b2c5b32..0ee292ec 100644 --- a/src/SeqCli/SeqCli.csproj +++ b/src/SeqCli/SeqCli.csproj @@ -29,6 +29,7 @@ +