Skip to content

Commit

Permalink
Merge pull request #271 from angularsen/agl/diagnostic-exception
Browse files Browse the repository at this point in the history
Log exception set in IDiagnosticContext
  • Loading branch information
nblumhardt authored Mar 4, 2022
2 parents f1cdcd7 + b8081d8 commit c15ab6d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector
// Enrich diagnostic context
_enrichDiagnosticContext?.Invoke(_diagnosticContext, httpContext);

if (!collector.TryComplete(out var collectedProperties))
if (!collector.TryComplete(out var collectedProperties, out var collectedException))
collectedProperties = NoProperties;

// Last-in (correctly) wins...
Expand All @@ -98,7 +98,7 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector
new LogEventProperty("Elapsed", new ScalarValue(elapsedMs))
});

var evt = new LogEvent(DateTimeOffset.Now, level, ex, _messageTemplate, properties);
var evt = new LogEvent(DateTimeOffset.Now, level, ex ?? collectedException, _messageTemplate, properties);
logger.Write(evt);

return false;
Expand Down
2 changes: 1 addition & 1 deletion src/Serilog.AspNetCore/Serilog.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

<ItemGroup>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.1-dev-00092" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Serilog.Filters;
using Serilog.AspNetCore.Tests.Support;

Expand Down Expand Up @@ -65,7 +66,51 @@ public async Task RequestLoggingMiddlewareShouldEnrich()
Assert.True(completionEvent.Properties.ContainsKey("Elapsed"));
}

WebApplicationFactory<TestStartup> Setup(ILogger logger, bool dispose, Action<RequestLoggingOptions> configureOptions = null)
[Fact]
public async Task RequestLoggingMiddlewareShouldEnrichWithCollectedExceptionIfNoUnhandledException()
{
var diagnosticContextException = new Exception("Exception set in diagnostic context");
var (sink, web) = Setup(options =>
{
options.EnrichDiagnosticContext += (diagnosticContext, _) =>
{
diagnosticContext.SetException(diagnosticContextException);
};
});

await web.CreateClient().GetAsync("/resource");

var completionEvent = sink.Writes.First(logEvent => Matching.FromSource<RequestLoggingMiddleware>()(logEvent));

Assert.Same(diagnosticContextException, completionEvent.Exception);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task RequestLoggingMiddlewareShouldEnrichWithUnhandledExceptionEvenIfExceptionIsSetInDiagnosticContext(bool setExceptionInDiagnosticContext)
{
var diagnosticContextException = new Exception("Exception set in diagnostic context");
var unhandledException = new Exception("Unhandled exception thrown in API action");
var (sink, web) = Setup(options =>
{
options.EnrichDiagnosticContext += (diagnosticContext, _) =>
{
if (setExceptionInDiagnosticContext)
diagnosticContext.SetException(diagnosticContextException);
};
}, actionCallback: _ => throw unhandledException);

Func<Task> act = () => web.CreateClient().GetAsync("/resource");

Exception thrownException = await Assert.ThrowsAsync<Exception>(act);
var completionEvent = sink.Writes.First(logEvent => Matching.FromSource<RequestLoggingMiddleware>()(logEvent));
Assert.Same(unhandledException, completionEvent.Exception);
Assert.Same(unhandledException, thrownException);
}

WebApplicationFactory<TestStartup> Setup(ILogger logger, bool dispose, Action<RequestLoggingOptions> configureOptions = null,
Action<HttpContext> actionCallback = null)
{
var web = _web.WithWebHostBuilder(
builder => builder
Expand All @@ -80,24 +125,29 @@ WebApplicationFactory<TestStartup> Setup(ILogger logger, bool dispose, Action<Re
.Configure(app =>
{
app.UseSerilogRequestLogging(configureOptions);
app.Run(_ => Task.CompletedTask); // 200 OK
app.Run(ctx =>
{
actionCallback?.Invoke(ctx);
return Task.CompletedTask;
}); // 200 OK
})
.UseSerilog(logger, dispose));

return web;
}

(SerilogSink, WebApplicationFactory<TestStartup>) Setup(Action<RequestLoggingOptions> configureOptions = null)
(SerilogSink, WebApplicationFactory<TestStartup>) Setup(Action<RequestLoggingOptions> configureOptions = null,
Action<HttpContext> actionCallback = null)
{
var sink = new SerilogSink();
var logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Sink(sink)
.CreateLogger();

var web = Setup(logger, true, configureOptions);
var web = Setup(logger, true, configureOptions, actionCallback);

return (sink, web);
}
}
}
}

0 comments on commit c15ab6d

Please sign in to comment.