serilog / serilog

Simple .NET logging with fully-structured events
https://serilog.net
Apache License 2.0
7.26k stars 798 forks source link

Built-in support for exception destructuring #194

Closed object closed 9 years ago

object commented 10 years ago

I wrote earlier a post on SO (http://stackoverflow.com/questions/25323607/exception-desctructuring-in-serilog), and I'll try to explain better what I mean. Let's look at this code:

        var exception = new ArgumentException("Exception message", "TestArgument", new Exception("Inner exception"));
        _logger.Debug(exception, "This is an exception", exception);

If I use JsonFormatter, I will get the following JSON:

{"Timestamp":"2014-08-21T11:47:15.7030000+02:00","Level":"Debug","MessageTemplate":"This is an exception","RenderedMessage":"This is an exception","Exception":"System.ArgumentException: Exception message\r\nParameternavn: TestArgument ---> System.Exception: Inner exception\r\n --- "}

Note that the JSON only include text representation of the exception, and since this is a JSON I would like it to be destructured or at least have a possibility to enable such option.

object commented 10 years ago

As a workaround I created the following class that added exception properties the generated JSON, but IMHO this is something that should be made available in Serilog:

public class StructuredExceptionEnricher : ILogEventEnricher
{
    public const string ExceptionPropertyName = "Exception";

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        if (logEvent == null)
            throw new ArgumentNullException("logEvent");

        if (logEvent.Exception != null)
        {
            var exceptionProperty = new LogEventProperty(
                ExceptionPropertyName,
                new DictionaryValue(logEvent.Exception.GetType().GetProperties().Select(
                    x => new KeyValuePair<ScalarValue, LogEventPropertyValue>(
                        new ScalarValue(x.Name),
                        new ScalarValue(x.GetValue(logEvent.Exception, null))))));
            logEvent.AddOrUpdateProperty(exceptionProperty);
        }
    }
}
nblumhardt commented 10 years ago

Thanks for the feedback, will keep this on the list :+1:

tbolon commented 10 years ago

FYI, you can read this discussion about how I handled it in my project. It's on seq google group, but is used as an Enricher.

object commented 10 years ago

Thanks @tbolon, I also ended up with custom enricher, but IMHO this is of so common use that it might be added as a part of core implementation.

nblumhardt commented 9 years ago

I've reopened #78 to try to condense exception-related stuff there.