Skip to content
Log exception details and custom properties that are not output in Exception.ToString().
Branch: master
Clone or download
dependabot-bot and RehanSaeed Bump Microsoft.NET.Test.Sdk from 16.0.0 to 16.0.1
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.0.0 to 16.0.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
Latest commit b48522e Mar 5, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Images Community Icon Dec 7, 2015
Source Bump version Dec 24, 2018
Tests Bump Microsoft.NET.Test.Sdk from 16.0.0 to 16.0.1 Mar 5, 2019
.editorconfig
.gitignore Ignore Cake tools folder Sep 9, 2016
.travis.yml update to bionic Dec 24, 2018
CHANGELOG.md Add support for OperationCancelledException and TaskCancelledException ( Nov 14, 2018
CONTRIBUTING.md
Key.snk Restructured project Sep 16, 2016
LICENSE Initial commit Dec 7, 2015
MinimumRecommendedRulesWithStyleCop.ruleset Enable SA1601 stylecop rule Feb 9, 2018
README.md Removing the extra dot Feb 19, 2019
Serilog.Exceptions.sln
appveyor.yml Upgrade to .NET Core 2.2 Dec 23, 2018
build.cake Optimise Pack command Nov 5, 2018
build.ps1
build.sh Add permissions to execute build.sh for Travis Sep 16, 2016

README.md

Serilog.Exceptions Logo Serilog.Exceptions

Serilog.Exceptions is an add-on to Serilog to log exception details and custom properties that are not output in Exception.ToString().

AppVeyor Build status Travis CI Build Status NuGet Package MyGet Package

What Does It Do?

Your JSON logs will now be supplemented with detailed exception information and even custom exception properties. Here is an example of what happens when you log a DbEntityValidationException from EntityFramework (This exception is notorious for having deeply nested custom properties which are not included in the .ToString()).

try
{
    ...
}
catch (DbEntityValidationException exception)
{
    logger.Error(exception, "Hello World");
}

The code above logs the following:

{
  "Timestamp": "2015-12-07T12:26:24.0557671+00:00",
  "Level": "Error",
  "MessageTemplate": "Hello World",
  "RenderedMessage": "Hello World",
  "Exception": "System.Data.Entity.Validation.DbEntityValidationException: Message",
  "Properties": {
    "ExceptionDetail": {
      "EntityValidationErrors": [
        {
          "Entry": null,
          "ValidationErrors": [
            {
              "PropertyName": "PropertyName",
              "ErrorMessage": "PropertyName is Required.",
              "Type": "System.Data.Entity.Validation.DbValidationError"
            }
          ],
          "IsValid": false,
          "Type": "System.Data.Entity.Validation.DbEntityValidationResult"
        }
      ],
      "Message": "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.",
      "Data": {},
      "InnerException": null,
      "TargetSite": null,
      "StackTrace": null,
      "HelpLink": null,
      "Source": null,
      "HResult": -2146232032,
      "Type": "System.Data.Entity.Validation.DbEntityValidationException"
    },
    "Source": "418169ff-e65f-456e-8b0d-42a0973c3577"
  }
}

Getting Started

Add the Serilog.Exceptions NuGet package to your project using the NuGet Package Manager or run the following command in the Package Console Window:

Install-Package Serilog.Exceptions

When setting up your logger, add the WithExceptionDetails() line like so:

using Serilog;
using Serilog.Exceptions;

ILogger logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .WriteTo.RollingFile(
        new JsonFormatter(renderMessage: true), 
        @"C:\logs\log-{Date}.txt")    
    .CreateLogger();

Make sure that the sink's formatter outputs enriched properties. Serilog.Sinks.Console and many more do not do that by default. You may need to add {Properties:j} to your sink's format template. For example, configuration for console sink may look like that:

.WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {Properties:j}")

Performance

This library has custom code to deal with extra properties on most common exception types and only falls back to using reflection to get the extra information if the exception is not supported by Serilog.Exceptions internally.

Custom Exception Destructurers

You may want to add support for destructuring your own exceptions without relying on reflection. To do this, create your own destructuring class implementing ExceptionDestructurer (You can take a look at this for ArgumentException), then simply add it like so:

using Serilog;
using Serilog.Exceptions;
using Serilog.Formatting.Json;

var exceptionDestructurers = new List<IExceptionDestructurer>();
exceptionDestructurers.AddRange(ExceptionEnricher.DefaultDestructurers);  // Add built in destructurers.
exceptionDestructurers.Add(new MyCustomExceptionDestructurer());          // Add your custom destructurer.

ILogger logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails(exceptionDestructurers)
    .WriteTo.RollingFile(
        new JsonFormatter(renderMessage: true), 
        @"C:\logs\log-{Date}.txt")    
    .CreateLogger();

If you write a destructurer that is not included in this project (even for a third party library), please contribute it.

Additional configuration

You can configure some additional properties of destructuring process, by passing custom destructuring options during setup:

.Enrich.WithExceptionDetails(new DestructuringOptionsBuilder().WithDefaultDestructurers().WithRootName("Exception"))

Currently following options are supported:

  • RootName: property name which will hold destructured exception, ExceptionDetail by default
  • Filter: object implementing IExceptionPropertyFilter that will have a chance to filter properties just before they are put in destructured exception object. Go to "Filtering properties" section for details.
  • DestructuringDepth: maximum depth of reflection based recursive destructuring process

Filtering properties

You may want to skip some properties of all or part your exception classes without directly creating or modyfying custom destructurers. Serilog.Exceptions supports this functionality using filter.

Most typical use case is the need to skip StackTrace and TargetSite. Serilog is already reporting them so you may want Serilog.Exceptions to skip them to save space and processing time. To do that you just need to modify a line in configuration:

.Enrich.WithExceptionDetails(new DestructuringOptionsBuilder().WithFilter(someFilter));

Filtering for other scenarios is also supported:

  • use WithIgnoreStackTraceAndTargetSiteExceptionFilter if you need to filter some other set of named properties
  • implement custom IExceptionPropertyFilter if you need some different filtering logic
  • use CompositeExceptionPropertyFilter to combine multiple filters

Contributing

Please look at the contributing guide.

Special Thanks

  • krajek & JeroenDragt - For adding filters to help ignore exception properties you don't want logged.
  • krajek - For helping with cyclic dependencies when using the reflection destructurer.
  • mraming - For logging properties that throw exceptions.
  • optical - For a huge VS 2017 upgrade PR.
  • Jérémie Bertrand - For making Serilog.Exceptions compatible with Mono.
  • krajek - For writing some much needed unit tests.
You can’t perform that action at this time.