From 276c1e43609ca967ea536efd441b0036fe425017 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Thu, 28 Dec 2017 15:11:42 -0800 Subject: [PATCH] Improve logging - output formatter selection --- .../DefaultOutputFormatterSelector.cs | 19 ++++- .../Internal/MvcCoreLoggerExtensions.cs | 69 +++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Infrastructure/DefaultOutputFormatterSelector.cs b/src/Microsoft.AspNetCore.Mvc.Core/Infrastructure/DefaultOutputFormatterSelector.cs index e101061b0e..61a62ec63f 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Infrastructure/DefaultOutputFormatterSelector.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Infrastructure/DefaultOutputFormatterSelector.cs @@ -78,6 +78,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure } } + _logger.RegisteredOutputFormatters(formatters); + var request = context.HttpContext.Request; var acceptableMediaTypes = GetAcceptableMediaTypes(request); var selectFormatterWithoutRegardingAcceptHeader = false; @@ -95,6 +97,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure { if (contentTypes.Count == 0) { + _logger.SelectingOutputFormatterUsingAcceptHeader(acceptableMediaTypes); + // Use whatever formatter can meet the client's request selectedFormatter = SelectFormatterUsingSortedAcceptHeaders( context, @@ -103,6 +107,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure } else { + _logger.SelectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes(acceptableMediaTypes, contentTypes); + // Verify that a content type from the context is compatible with the client's request selectedFormatter = SelectFormatterUsingSortedAcceptHeadersAndContentTypes( context, @@ -111,11 +117,14 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure contentTypes); } - if (selectedFormatter == null && !_returnHttpNotAcceptable) + if (selectedFormatter == null) { _logger.NoFormatterFromNegotiation(acceptableMediaTypes); - selectFormatterWithoutRegardingAcceptHeader = true; + if (!_returnHttpNotAcceptable) + { + selectFormatterWithoutRegardingAcceptHeader = true; + } } } @@ -123,12 +132,16 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure { if (contentTypes.Count == 0) { + _logger.SelectingOutputFormatterWithoutUsingContentTypes(); + selectedFormatter = SelectFormatterNotUsingContentType( context, formatters); } else { + _logger.SelectingOutputFormatterUsingContentTypes(contentTypes); + selectedFormatter = SelectFormatterUsingAnyAcceptableContentType( context, formatters, @@ -180,6 +193,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure throw new ArgumentNullException(nameof(formatters)); } + _logger.SelectFirstCanWriteFormatter(); + foreach (var formatter in formatters) { formatterContext.ContentType = new StringSegment(); diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs index c20e14f764..ed5e2354e7 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs @@ -100,7 +100,13 @@ namespace Microsoft.AspNetCore.Mvc.Internal private static readonly Action _actionDoesNotSupportFormatFilterContentType; private static readonly Action _cannotApplyFormatFilterContentType; private static readonly Action _actionDoesNotExplicitlySpecifyContentTypes; + private static readonly Action, Exception> _selectingOutputFormatterUsingAcceptHeader; + private static readonly Action, MediaTypeCollection, Exception> _selectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes; + private static readonly Action _selectingOutputFormatterWithoutUsingContentTypes; + private static readonly Action _selectingOutputFormatterUsingContentTypes; + private static readonly Action _selectingFirstCanWriteFormatter; private static readonly Action _notMostEffectiveFilter; + private static readonly Action, Exception> _registeredOutputFormatters; static MvcCoreLoggerExtensions() { @@ -368,6 +374,69 @@ namespace Microsoft.AspNetCore.Mvc.Internal LogLevel.Debug, 5, "Current action does not explicitly specify any content types for the response."); + + _selectingOutputFormatterUsingAcceptHeader = LoggerMessage.Define>( + LogLevel.Debug, + 6, + "Attempting to select an output formatter based on Accept header '{AcceptHeader}'."); + + _selectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes = LoggerMessage.Define, MediaTypeCollection>( + LogLevel.Debug, + 7, + "Attempting to select an output formatter based on Accept header '{AcceptHeader}' and explicitly specified content types '{ExplicitContentTypes}'. The content types in the accept header must be a subset of the explicitly set content types."); + + _selectingOutputFormatterWithoutUsingContentTypes = LoggerMessage.Define( + LogLevel.Debug, + 8, + "Attempting to select an output formatter without using a content type as no explicit content types were specified for the response."); + + _selectingOutputFormatterUsingContentTypes = LoggerMessage.Define( + LogLevel.Debug, + 9, + "Attempting to select the first output formatter in the output formatters list which supports a content type from the explicitly specified content types '{ExplicitContentTypes}'."); + + _selectingFirstCanWriteFormatter = LoggerMessage.Define( + LogLevel.Debug, + 10, + "Attempting to select the first formatter in the output formatters list which can write the result."); + + _registeredOutputFormatters = LoggerMessage.Define>( + LogLevel.Debug, + 11, + "List of registered output formatters, in the following order: {OutputFormatters}"); + } + + public static void RegisteredOutputFormatters(this ILogger logger, IEnumerable outputFormatters) + { + _registeredOutputFormatters(logger, outputFormatters, null); + } + + public static void SelectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes( + this ILogger logger, + IEnumerable acceptHeader, + MediaTypeCollection mediaTypeCollection) + { + _selectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes(logger, acceptHeader, mediaTypeCollection, null); + } + + public static void SelectingOutputFormatterUsingAcceptHeader(this ILogger logger, IEnumerable acceptHeader) + { + _selectingOutputFormatterUsingAcceptHeader(logger, acceptHeader, null); + } + + public static void SelectingOutputFormatterUsingContentTypes(this ILogger logger, MediaTypeCollection mediaTypeCollection) + { + _selectingOutputFormatterUsingContentTypes(logger, mediaTypeCollection, null); + } + + public static void SelectingOutputFormatterWithoutUsingContentTypes(this ILogger logger) + { + _selectingOutputFormatterWithoutUsingContentTypes(logger, null); + } + + public static void SelectFirstCanWriteFormatter(this ILogger logger) + { + _selectingFirstCanWriteFormatter(logger, null); } public static IDisposable ActionScope(this ILogger logger, ActionDescriptor action)