-
Notifications
You must be signed in to change notification settings - Fork 161
Added W3CExtendedLogLayout for writing W3C Extended Logs #700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.AspNetCore.Http; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace NLog.Web | ||
| { | ||
| /// <summary> | ||
| /// Middleware that writes all requests to Logger named "RequestLogging" | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// - LogLevel.Error - Request failed with exception<br/> | ||
| /// - LogLevel.Warn - Request completed with unsucessful StatusCode<br/> | ||
| /// - LogLevel.Info - Request completed standard StatusCode<br/> | ||
| /// </remarks> | ||
| public class NLogRequestLoggingMiddleware | ||
| { | ||
| private readonly RequestDelegate _next; | ||
| private readonly NLogRequestLoggingOptions _options; | ||
| private readonly Microsoft.Extensions.Logging.ILogger _logger; | ||
|
|
||
| /// <summary> | ||
| /// Initializes new instance of the <see cref="NLogRequestLoggingMiddleware"/> class | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Use the following in Startup.cs: | ||
| /// <code> | ||
| /// public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||
| /// { | ||
| /// app.UseMiddleware<NLog.Web.RequestLoggingMiddleware>(); | ||
| /// } | ||
| /// </code> | ||
| /// </remarks> | ||
| public NLogRequestLoggingMiddleware(RequestDelegate next, NLogRequestLoggingOptions options = default, ILoggerFactory loggerFactory = default) | ||
| { | ||
| _next = next; | ||
| _options = options ?? NLogRequestLoggingOptions.Default; | ||
| _logger = loggerFactory?.CreateLogger(_options.LoggerName ?? NLogRequestLoggingOptions.Default.LoggerName) ?? Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Executes the middleware. | ||
| /// </summary> | ||
| public async Task Invoke(HttpContext httpContext) | ||
| { | ||
| try | ||
| { | ||
| await _next(httpContext); | ||
| LogHttpRequest(httpContext, null); | ||
| } | ||
| catch (Exception exception) when (LogHttpRequest(httpContext, exception)) | ||
| { | ||
| // Logging complete | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Exception Filter for better capture of thread-execution-context (Ex. AsyncLocal-state) | ||
| /// </summary> | ||
| private bool LogHttpRequest(HttpContext httpContext, Exception exception) | ||
| { | ||
| if (exception != null) | ||
| { | ||
| _logger.LogError(exception, "HttpRequest Exception"); | ||
| } | ||
| else | ||
| { | ||
| var statusCode = httpContext.Response?.StatusCode ?? 0; | ||
| if (statusCode < 100 || statusCode >= 400) | ||
| { | ||
| _logger.LogWarning("HttpRequest Failed"); | ||
| } | ||
| else | ||
| { | ||
| _logger.LogInformation("HttpRequest Completed"); | ||
| } | ||
| } | ||
|
|
||
| return false; // Exception Filter should not suppress the Exception | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| namespace NLog.Web | ||
| { | ||
| /// <summary> | ||
| /// Options configuration for <see cref="NLogRequestLoggingMiddleware"/> | ||
| /// </summary> | ||
| public sealed class NLogRequestLoggingOptions | ||
| { | ||
| internal static readonly NLogRequestLoggingOptions Default = new NLogRequestLoggingOptions(); | ||
|
|
||
| /// <summary> | ||
| /// Logger-name used for logging http-requests | ||
| /// </summary> | ||
| public string LoggerName { get; set; } = "NLogRequestLogging"; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| using System; | ||
| using System.Web; | ||
|
|
||
| namespace NLog.Web | ||
| { | ||
| /// <summary> | ||
| /// HttpModule that writes all requests to Logger named "RequestLogging" | ||
| /// </summary> | ||
| public class NLogRequestLoggingModule : IHttpModule | ||
| { | ||
| private static readonly NLog.Logger Logger = NLog.LogManager.GetLogger("NLogRequestLogging"); | ||
|
|
||
| void IHttpModule.Init(HttpApplication context) | ||
| { | ||
| context.EndRequest += LogHttpRequest; | ||
| } | ||
|
|
||
| private void LogHttpRequest(object sender, EventArgs e) | ||
| { | ||
| Exception exception = null; | ||
| int statusCode = 0; | ||
|
|
||
| try | ||
| { | ||
| exception = HttpContext.Current?.Server?.GetLastError(); | ||
| statusCode = HttpContext.Current?.Response?.StatusCode ?? 0; | ||
| } | ||
| catch | ||
| { | ||
| // Nothing to do | ||
| } | ||
| finally | ||
| { | ||
| if (exception != null) | ||
| Logger.Error(exception, "HttpRequest Exception"); | ||
| else if (statusCode < 100 || statusCode >= 400) | ||
| Logger.Warn("HttpRequest Failed"); | ||
| else | ||
| Logger.Info("HttpRequest Completed"); | ||
| } | ||
| } | ||
|
|
||
| void IHttpModule.Dispose() | ||
| { | ||
| // Nothing here to do | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| using System; | ||
| using System.Text; | ||
| using NLog.LayoutRenderers; | ||
| using NLog.Web.Internal; | ||
|
|
||
| namespace NLog.Web.LayoutRenderers | ||
| { | ||
| /// <summary> | ||
| /// ASP.NET request contentlength of the posted body | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// ${aspnet-request-contentlength} | ||
| /// </remarks> | ||
| [LayoutRenderer("aspnet-request-contentlength")] | ||
| public class AspNetRequestContentLength : AspNetLayoutRendererBase | ||
| { | ||
| /// <summary> | ||
| /// Renders the ASP.NET posted body | ||
| /// </summary> | ||
| /// <param name="builder">The <see cref="StringBuilder" /> to append the rendered data to.</param> | ||
| /// <param name="logEvent">Logging event.</param> | ||
| protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) | ||
| { | ||
| var httpRequest = HttpContextAccessor.HttpContext.TryGetRequest(); | ||
| if (httpRequest == null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| long? contentLength = httpRequest.ContentLength; | ||
| if (contentLength > 0L) | ||
| { | ||
| builder.Append(contentLength.Value); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using System.Text; | ||
| using NLog.LayoutRenderers; | ||
| using NLog.Web.Internal; | ||
|
|
||
| namespace NLog.Web.LayoutRenderers | ||
| { | ||
| /// <summary> | ||
| /// ASP.NET Response ContentLength | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// ${aspnet-response-contentlength} | ||
| /// </remarks> | ||
| [LayoutRenderer("aspnet-response-contentlength")] | ||
| public class AspNetResponseContentLength : AspNetLayoutRendererBase | ||
| { | ||
| /// <summary> | ||
| /// ASP.NET Http Response Status Code | ||
| /// </summary> | ||
| /// <param name="builder">The <see cref="StringBuilder" /> to append the rendered data to.</param> | ||
| /// <param name="logEvent">Logging event.</param> | ||
| protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) | ||
| { | ||
| var httpResponse = HttpContextAccessor.HttpContext.TryGetResponse(); | ||
| if (httpResponse == null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| #if ASP_NET_CORE | ||
| var contentLength = httpResponse.ContentLength; | ||
| #else | ||
| var contentLength = httpResponse.OutputStream?.Length; | ||
| #endif | ||
| if (contentLength > 0L) | ||
| { | ||
| builder.Append(contentLength); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using NLog.Config; | ||
| using NLog.Layouts; | ||
|
|
||
| namespace NLog.Web.Layouts | ||
| { | ||
| /// <summary> | ||
| /// Field in W3C Extended Formatted event | ||
| /// </summary> | ||
| [NLogConfigurationItem] | ||
| public class W3CExtendedLogField | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="W3CExtendedLogField" /> class. | ||
| /// </summary> | ||
| public W3CExtendedLogField() | ||
| : this(null, null) | ||
| { | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="W3CExtendedLogField" /> class. | ||
| /// </summary> | ||
| /// <param name="name">The name of the column.</param> | ||
| /// <param name="layout">The layout of the column.</param> | ||
| public W3CExtendedLogField(string name, Layout layout) | ||
| { | ||
| Name = name; | ||
| Layout = layout; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the name of the field. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Standard field prefixes:<br/> | ||
| /// * s- = server details<br/> | ||
| /// * c- = client details<br/> | ||
| /// * cs- = client to server request details<br/> | ||
| /// * sc- = server to client response details<br/> | ||
| /// </remarks> | ||
| /// <docgen category='W3C Field Options' order='10' /> | ||
| public string Name { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the layout of the field. | ||
| /// </summary> | ||
| /// <docgen category='W3C Field Options' order='10' /> | ||
| [RequiredParameter] | ||
| public Layout Layout { get; set; } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.