Skip to content

Commit fbd2c34

Browse files
Add option to add ElapsedMs to the HttpContext before enrishing diagnostic contect.
1 parent dc1181c commit fbd2c34

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class RequestLoggingMiddleware
3232
readonly Func<HttpContext, string, double, int, IEnumerable<LogEventProperty>> _getMessageTemplateProperties;
3333
readonly ILogger? _logger;
3434
readonly bool _includeQueryInRequestPath;
35+
readonly bool _addElapsedToHttpContext;
3536
static readonly LogEventProperty[] NoProperties = [];
3637

3738
public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnosticContext, RequestLoggingOptions options)
@@ -45,6 +46,7 @@ public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnost
4546
_messageTemplate = new MessageTemplateParser().Parse(options.MessageTemplate);
4647
_logger = options.Logger?.ForContext<RequestLoggingMiddleware>();
4748
_includeQueryInRequestPath = options.IncludeQueryInRequestPath;
49+
_addElapsedToHttpContext = options.AddElapsedToHttpContext;
4850
_getMessageTemplateProperties = options.GetMessageTemplateProperties;
4951
}
5052

@@ -82,6 +84,11 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector
8284

8385
if (!logger.IsEnabled(level)) return false;
8486

87+
if (_addElapsedToHttpContext)
88+
{
89+
httpContext.Items.Add(RequestLoggingOptions.HttpContextItemsElapsedKey, elapsedMs);
90+
}
91+
8592
_enrichDiagnosticContext?.Invoke(_diagnosticContext, httpContext);
8693

8794
if (!collector.TryComplete(out var collectedProperties, out var collectedException))

src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class RequestLoggingOptions
2626
{
2727
const string DefaultRequestCompletionMessageTemplate =
2828
"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms";
29-
29+
3030
static LogEventLevel DefaultGetLevel(HttpContext ctx, double _, Exception? ex) =>
3131
ex != null
3232
? LogEventLevel.Error
@@ -41,6 +41,11 @@ static IEnumerable<LogEventProperty> DefaultGetMessageTemplateProperties(HttpCon
4141
new LogEventProperty("StatusCode", new ScalarValue(statusCode)),
4242
new LogEventProperty("Elapsed", new ScalarValue(elapsedMs))
4343
];
44+
45+
/// <summary>
46+
/// The key used to add the ElapsedMs value to <see cref="HttpContext"/> <c>Items</c> collection
47+
/// </summary>
48+
public const string HttpContextItemsElapsedKey = "Serilog.AspNetCore.ElapsedMs";
4449

4550
/// <summary>
4651
/// Gets or sets the message template. The default value is
@@ -80,6 +85,12 @@ static IEnumerable<LogEventProperty> DefaultGetMessageTemplateProperties(HttpCon
8085
/// that is attached to request log events. The default is <c>false</c>.
8186
/// </summary>
8287
public bool IncludeQueryInRequestPath { get; set; }
88+
89+
90+
/// <summary>
91+
/// Add the elapsed millisecond value to the <see cref="HttpContext"/> <c>Items</c> collection before invoking <c>EnrichDiagnosticContext</c>
92+
/// </summary>
93+
public bool AddElapsedToHttpContext { get; set; }
8394

8495
/// <summary>
8596
/// A function to specify the values of the MessageTemplateProperties.

test/Serilog.AspNetCore.Tests/SerilogWebHostBuilderExtensionsTests.cs

+23
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@ public async Task RequestLoggingMiddlewareShouldEnrich()
6464
Assert.True(completionEvent.Properties.ContainsKey("Elapsed"));
6565
}
6666

67+
68+
[Fact]
69+
public async Task RequestLoggingMiddlewareShouldEnrichWithElapsed()
70+
{
71+
var (sink, web) = Setup(options =>
72+
{
73+
options.AddElapsedToHttpContext = true;
74+
options.EnrichDiagnosticContext += (diagnosticContext, httpContext) =>
75+
{
76+
var elapsedValue = (double)(httpContext.Items[RequestLoggingOptions.HttpContextItemsElapsedKey] ?? -0.1);
77+
diagnosticContext.Set("ElapsedValue", elapsedValue);
78+
};
79+
});
80+
81+
await web.CreateClient().GetAsync("/resource");
82+
83+
Assert.NotEmpty(sink.Writes);
84+
85+
var completionEvent = sink.Writes.First(logEvent => Matching.FromSource<RequestLoggingMiddleware>()(logEvent));
86+
87+
Assert.True((double)completionEvent.Properties["ElapsedValue"].LiteralValue()! > 0);
88+
}
89+
6790
[Fact]
6891
public async Task RequestLoggingMiddlewareShouldEnrichWithCustomisedProperties()
6992
{

0 commit comments

Comments
 (0)