Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Infrastructure/LeanCode.Logging/ContextualLogger.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Serilog;
using Serilog.Events;
using Serilog.Parsing;

namespace LeanCode.Logging;

Expand All @@ -8,4 +10,11 @@ public class ContextualLogger<T>(ILogger logger) : ILogger<T>
private readonly ILogger logger = logger.ForContext<T>();

public void Write(LogEvent logEvent) => logger.Write(logEvent);

public bool BindMessageTemplate(
string messageTemplate,
object?[]? propertyValues,
[NotNullWhen(true)] out MessageTemplate? parsedTemplate,
[NotNullWhen(true)] out IEnumerable<LogEventProperty>? boundProperties
) => logger.BindMessageTemplate(messageTemplate, propertyValues, out parsedTemplate, out boundProperties);
}
14 changes: 14 additions & 0 deletions src/Infrastructure/LeanCode.Logging/NullLogger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using Serilog.Events;
using Serilog.Parsing;

namespace LeanCode.Logging;

Expand All @@ -7,4 +9,16 @@ public class NullLogger<T> : ILogger<T>
public static readonly NullLogger<T> Instance = new();

public void Write(LogEvent logEvent) { }

public bool BindMessageTemplate(
string messageTemplate,
object?[]? propertyValues,
[NotNullWhen(true)] out MessageTemplate? parsedTemplate,
[NotNullWhen(true)] out IEnumerable<LogEventProperty>? boundProperties
)
{
parsedTemplate = null;
boundProperties = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Xunit;

namespace LeanCode.Logging.Tests;

public class ContextualLoggerDestructuringTests
{
private sealed class DestructuringMarker { }

[Fact]
public void ContextualLogger_applies_configured_destructuring_policies_to_message_templates()
{
var sink = new SingleLogEventCapturerSink();

using var log = new LoggerConfiguration().Destructure.With<RightSanitizer>().WriteTo.Sink(sink).CreateLogger();

Logging.ILogger<DestructuringMarker> contextualLogger = new ContextualLogger<DestructuringMarker>(log);

contextualLogger.Information("{@Payload}", Payload.Workable);

Assert.NotNull(sink.LastEvent);
var prop = sink.LastEvent!.Properties["Payload"];
var rendered = prop.ToString();

Assert.Contains(BaseSanitizer<Payload>.Placeholder, rendered, StringComparison.Ordinal);
Assert.DoesNotContain("NOT PLACEHOLDER", rendered, StringComparison.Ordinal);
}

private sealed class SingleLogEventCapturerSink : ILogEventSink
{
public LogEvent LastEvent { get; private set; } = null!;

public void Emit(LogEvent logEvent) => LastEvent = logEvent;
}
}
Loading