asp.net-core.net-coreserilogserilog-sinks-consoleserilog-enricher

Serilog console sink that logs exception message without stacktrace


Some of Serilog's standard template properties can be customised, e.g. {Timestamp:HH:mm:ss}, {Level:u3} and {Message:lj}. Not so for {Exception}, which prints both message and stack trace, on multiple lines.

For the human-readable console sink, a stack trace adds significant noise and friction, especially when tailing a remote docker container which is already ugly (no colour, for example). If I need the stack trace, I would consult a durable sink, e.g. file, Seq.

How can I log just the exception message to the console sink?

(I'm aware of Serilog.Expressions, but for something so simple I hope there's a solution without another dependency.)


Solution

  • As per a comment on the repo, here's a solution using a custom enricher.

    Create the enricher ExceptionMessageEnricher.cs:

    using Serilog.Core;
    using Serilog.Events;
    
    namespace Serilog.Enrichers;
    
    public sealed class ExceptionMessageEnricher : ILogEventEnricher
    {
      public const string PROPERTY_NAME = "ExceptionMessage";
    
      public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
      {
        ArgumentNullException.ThrowIfNull(logEvent, nameof(logEvent));
        ArgumentNullException.ThrowIfNull(propertyFactory, nameof(propertyFactory));
    
        if (logEvent.Exception == null) return;
    
        var property = propertyFactory.CreateProperty(PROPERTY_NAME, $"\"{logEvent.Exception.Message}\"");
        logEvent.AddPropertyIfAbsent(property);
      }
    
    }
    

    Then use it in the Serilog config:

    var outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {ExceptionMessage}{NewLine}";
    
    services.AddSerilog((services, config) => config
      // ...
      .WriteTo.Logger(x => x
        .Enrich.With<ExceptionMessageEnricher>()
        .WriteTo.Console(outputTemplate:outputTemplate)
      )
    );
    

    A rendered message would look something like this:

    [13:04:44 ERR] Something bad happened "The exception message"
    

    Notes:

    An alternative approach, using Serilog.Expressions: {Inspect(@x).Message}.