From b3b87df3209f2e1410b491108f8368da994cc14d Mon Sep 17 00:00:00 2001 From: mika kuns Date: Thu, 4 Jun 2026 19:07:38 +0200 Subject: [PATCH] feat(logging): default TaskId enricher with passing tests --- src/ClaudeDo.Logging/DefaultTaskIdEnricher.cs | 15 ++++++ src/ClaudeDo.Logging/Placeholder.cs | 3 -- .../ClaudeDo.Worker.Tests.csproj | 1 + .../Logging/DefaultTaskIdEnricherTests.cs | 49 +++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/ClaudeDo.Logging/DefaultTaskIdEnricher.cs delete mode 100644 src/ClaudeDo.Logging/Placeholder.cs create mode 100644 tests/ClaudeDo.Worker.Tests/Logging/DefaultTaskIdEnricherTests.cs diff --git a/src/ClaudeDo.Logging/DefaultTaskIdEnricher.cs b/src/ClaudeDo.Logging/DefaultTaskIdEnricher.cs new file mode 100644 index 0000000..cea4b60 --- /dev/null +++ b/src/ClaudeDo.Logging/DefaultTaskIdEnricher.cs @@ -0,0 +1,15 @@ +using Serilog.Core; +using Serilog.Events; + +namespace ClaudeDo.Logging; + +/// Ensures every log event carries a TaskId property (defaulting to "-") +/// so the output template's [{TaskId}] column never renders the raw token. +public sealed class DefaultTaskIdEnricher : ILogEventEnricher +{ + public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) + { + if (!logEvent.Properties.ContainsKey("TaskId")) + logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TaskId", "-")); + } +} diff --git a/src/ClaudeDo.Logging/Placeholder.cs b/src/ClaudeDo.Logging/Placeholder.cs deleted file mode 100644 index c72b270..0000000 --- a/src/ClaudeDo.Logging/Placeholder.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace ClaudeDo.Logging; - -internal static class Placeholder; diff --git a/tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj b/tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj index bfa4f50..c2fb766 100644 --- a/tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj +++ b/tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj @@ -25,6 +25,7 @@ + diff --git a/tests/ClaudeDo.Worker.Tests/Logging/DefaultTaskIdEnricherTests.cs b/tests/ClaudeDo.Worker.Tests/Logging/DefaultTaskIdEnricherTests.cs new file mode 100644 index 0000000..d360f1f --- /dev/null +++ b/tests/ClaudeDo.Worker.Tests/Logging/DefaultTaskIdEnricherTests.cs @@ -0,0 +1,49 @@ +using ClaudeDo.Logging; +using Serilog; +using Serilog.Context; +using Serilog.Core; +using Serilog.Events; + +namespace ClaudeDo.Worker.Tests.Logging; + +public sealed class DefaultTaskIdEnricherTests +{ + private sealed class CollectingSink : ILogEventSink + { + public List Events { get; } = new(); + public void Emit(LogEvent logEvent) => Events.Add(logEvent); + } + + [Fact] + public void AddsDash_WhenNoTaskIdInScope() + { + var sink = new CollectingSink(); + using var logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .Enrich.With(new DefaultTaskIdEnricher()) + .WriteTo.Sink(sink) + .CreateLogger(); + + logger.Information("hello"); + + var prop = Assert.Single(sink.Events).Properties["TaskId"]; + Assert.Equal("\"-\"", prop.ToString()); + } + + [Fact] + public void KeepsPushedTaskId_WhenInScope() + { + var sink = new CollectingSink(); + using var logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .Enrich.With(new DefaultTaskIdEnricher()) + .WriteTo.Sink(sink) + .CreateLogger(); + + using (LogContext.PushProperty("TaskId", "task-42")) + logger.Information("hello"); + + var prop = Assert.Single(sink.Events).Properties["TaskId"]; + Assert.Equal("\"task-42\"", prop.ToString()); + } +}