Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork54
Log exception details and custom properties that are not output in Exception.ToString().
License
RehanSaeed/Serilog.Exceptions
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Serilog.Exceptions is an add-on toSerilog to log exception details and custom properties that are not output inException.ToString().
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 aDbEntityValidationException from EntityFramework (This exception is notorious for having deeply nested custom properties which are not included in the.ToString()).
try{ ...}catch(DbEntityValidationExceptionexception){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" }}Warning Entity Framework Core Users:If you are using Entity Framework with Serilog.Exceptions you should read thefollowing instructions.
Add theSerilog.Exceptions NuGet package to your project using the NuGet Package Manager or run the following command in the Package Console Window:
dotnet add package Serilog.Exceptions
When setting up your logger, add theWithExceptionDetails() line like so:
usingSerilog;usingSerilog.Exceptions;ILoggerlogger=newLoggerConfiguration().Enrich.WithExceptionDetails().WriteTo.RollingFile(newJsonFormatter(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}")
Alternatively to fluent configuration setting can be stored in application configuration usingSerilog.Settings.Configuration:
{"Serilog": {"Using": ["Serilog.Exceptions" ],"Enrich": ["WithExceptionDetails" ],"WriteTo": [ {"Name":"Console" } ] }}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. Reflection overhead is present but minimal, because all the expensive relection-based operations are done only once per exception-type.
Add theSerilog.Exceptions.SqlServer NuGet package to your project to avoid the reflection based destructurer forSqlException when usingSystem.Data.SqlClient:
dotnet add package Serilog.Exceptions.SqlServer
Add theSqlExceptionDestructurer during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newSqlExceptionDestructurer()}))
Add theSerilog.Exceptions.MsSqlServer NuGet package to your project to avoid the reflection based destructurer forSqlException when usingMicrosoft.Data.SqlClient:
dotnet add package Serilog.Exceptions.MsSqlServer
Add theSqlExceptionDestructurer during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newSqlExceptionDestructurer()}))
WarningIf you are using Entity Framework with Serilog.Exceptions you must follow the instructions below, otherwise in certain cases your entire database will be logged! This is because the exceptions in Entity Framework have properties that link to the entire database schema in them (See#100,aspnet/EntityFrameworkCore#15214). Version 8 or newer of Serilog.Exceptions reduces the problem by preventing the destructure of properties that implement
IQueryablebut the rest of theDbContextobject will still get logged.
Add theSerilog.Exceptions.EntityFrameworkCore NuGet package to your project when using EntityFrameworkCore in your project
dotnet add package Serilog.Exceptions.EntityFrameworkCore
Add theDbUpdateExceptionDestructurer during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newDbUpdateExceptionDestructurer()}))
Add theSerilog.Exceptions.Refit NuGet package to your project to provide detailed logging for theApiException when usingRefit:
dotnet add package Serilog.Exceptions.Refit
Add theApiExceptionDestructurer during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newApiExceptionDestructurer()}))
Depending on your Serilog setup, commonSystem.Exception properties may already be logged. To omit the logging of these properties, use the overloadedconstructor as follows:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newApiExceptionDestructurer(destructureCommonExceptionProperties:false)}))
The default configuration logs the following properties of anApiException:
UriStatusCode
In addition, theApiException.Content property can be logged with the following setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newApiExceptionDestructurer(destructureHttpContent:true)}))
Be careful with this option as the HTTP body could be very large and/or contain sensitive information.
Add theSerilog.Exceptions.Grpc NuGet package to your project to avoid the reflection based destructurer forRpcException when usingGrpc.Net.Client:
dotnet add package Serilog.Exceptions.Grpc
Add theRpcExceptionDestructurer during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newRpcExceptionDestructurer()}))
You may want to add support for destructuring your own exceptions without relying on reflection. To do this, create your own destructuring class implementingExceptionDestructurer (You can take a look atthis forArgumentException), then simply add it like so:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithDestructurers(new[]{newMyCustomExceptionDestructurer()}))
If you write a destructurer that is not included in this project (even for a third party library), please contribute it.
You can configure some additional properties of destructuring process, by passing custom destructuring options during setup:
.Enrich.WithExceptionDetails(newDestructuringOptionsBuilder().WithDefaultDestructurers().WithRootName("Exception"))
Currently following options are supported:
RootName: The property name which will hold destructured exception,ExceptionDetailby default.Filter: The object implementingIExceptionPropertyFilterthat will have a chance to filter properties just before they are put in destructured exception object. Go to "Filtering properties" section for details.DestructuringDepth: The maximum depth of reflection based recursive destructuring process.ReflectionBasedDestructurer: Reflection based destructurer is enabled by default, but can be disabled in case you want to have complete control over destructuring process. You will have to register destructurers for all exceptions explicitly.
You may want to skip some properties of all or part your exception classes without directly creating or modifying custom destructurers. Serilog.Exceptions supports this functionality using a filter.
Most typical use case is the need to skipStackTrace andTargetSite. 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(newDestructuringOptionsBuilder().WithFilter(someFilter));
Filtering for other scenarios is also supported:
- Use
WithIgnoreStackTraceAndTargetSiteExceptionFilterif you need to filter some other set of named properties - Implement custom
IExceptionPropertyFilterif you need some different filtering logic - Use
CompositeExceptionPropertyFilterto combine multiple filters
| Name | Operating System | Status |
|---|---|---|
| Azure Pipelines | Ubuntu | |
| Azure Pipelines | Mac | |
| Azure Pipelines | Windows | |
| Azure Pipelines | Overall | |
| GitHub Actions | Ubuntu, Mac & Windows | |
| AppVeyor | Ubuntu, Mac & Windows |
Please view thecontributing guide for more information.
- 304NotModified - Added Markdown syntax highlighting.
- joelweiss - Added Entity Framework Core destructurers.
- 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.
About
Log exception details and custom properties that are not output in Exception.ToString().
Topics
Resources
License
Code of conduct
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
