Skip to content
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

Update Mvc to use LoggerMessageAttribute #38658

Merged
merged 11 commits into from
Jan 20, 2022
27 changes: 21 additions & 6 deletions src/Mvc/Mvc.Core/src/Filters/DisableRequestSizeLimitFilter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.AspNetCore.Http.Features;
Expand All @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters;
/// A filter that sets <see cref="IHttpMaxRequestBodySizeFeature.MaxRequestBodySize"/>
/// to <c>null</c>.
/// </summary>
internal class DisableRequestSizeLimitFilter : IAuthorizationFilter, IRequestSizePolicy
internal partial class DisableRequestSizeLimitFilter : IAuthorizationFilter, IRequestSizePolicy
{
private readonly ILogger _logger;

Expand Down Expand Up @@ -39,24 +39,39 @@ public void OnAuthorization(AuthorizationFilterContext context)
var effectivePolicy = context.FindEffectivePolicy<IRequestSizePolicy>();
if (effectivePolicy != null && effectivePolicy != this)
{
_logger.NotMostEffectiveFilter(GetType(), effectivePolicy.GetType(), typeof(IRequestSizePolicy));
Log.NotMostEffectiveFilter(_logger, GetType(), effectivePolicy.GetType(), typeof(IRequestSizePolicy));
return;
}

var maxRequestBodySizeFeature = context.HttpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();

if (maxRequestBodySizeFeature == null)
{
_logger.FeatureNotFound();
Log.FeatureNotFound(_logger);
}
else if (maxRequestBodySizeFeature.IsReadOnly)
{
_logger.FeatureIsReadOnly();
Log.FeatureIsReadOnly(_logger);
}
else
{
maxRequestBodySizeFeature.MaxRequestBodySize = null;
_logger.RequestBodySizeLimitDisabled();
Log.RequestBodySizeLimitDisabled(_logger);
}
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Warning, "A request body size limit could not be applied. This server does not support the IHttpRequestBodySizeFeature.", EventName = "FeatureNotFound")]
public static partial void FeatureNotFound(ILogger logger);

[LoggerMessage(2, LogLevel.Warning, "A request body size limit could not be applied. The IHttpRequestBodySizeFeature for the server is read-only.", EventName = "FeatureIsReadOnly")]
public static partial void FeatureIsReadOnly(ILogger logger);

[LoggerMessage(3, LogLevel.Debug, "The request body size limit has been disabled.", EventName = "RequestBodySizeLimitDisabled")]
public static partial void RequestBodySizeLimitDisabled(ILogger logger);

[LoggerMessage(4, LogLevel.Debug, "Execution of filter {OverriddenFilter} is preempted by filter {OverridingFilter} which is the most effective filter implementing policy {FilterPolicy}.", EventName = "NotMostEffectiveFilter")]
public static partial void NotMostEffectiveFilter(ILogger logger, Type overriddenFilter, Type overridingFilter, Type filterPolicy);
}
}
20 changes: 16 additions & 4 deletions src/Mvc/Mvc.Core/src/Filters/RequestFormLimitsFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters;
/// <summary>
/// A filter that configures <see cref="FormOptions"/> for the current request.
/// </summary>
internal class RequestFormLimitsFilter : IAuthorizationFilter, IRequestFormLimitsPolicy
internal partial class RequestFormLimitsFilter : IAuthorizationFilter, IRequestFormLimitsPolicy
{
private readonly ILogger _logger;

Expand All @@ -30,7 +30,7 @@ public void OnAuthorization(AuthorizationFilterContext context)
var effectivePolicy = context.FindEffectivePolicy<IRequestFormLimitsPolicy>();
if (effectivePolicy != null && effectivePolicy != this)
{
_logger.NotMostEffectiveFilter(GetType(), effectivePolicy.GetType(), typeof(IRequestFormLimitsPolicy));
Log.NotMostEffectiveFilter(_logger, GetType(), effectivePolicy.GetType(), typeof(IRequestFormLimitsPolicy));
return;
}

Expand All @@ -41,11 +41,23 @@ public void OnAuthorization(AuthorizationFilterContext context)
{
// Request form has not been read yet, so set the limits
features.Set<IFormFeature>(new FormFeature(context.HttpContext.Request, FormOptions));
_logger.AppliedRequestFormLimits();
Log.AppliedRequestFormLimits(_logger);
}
else
{
_logger.CannotApplyRequestFormLimits();
Log.CannotApplyRequestFormLimits(_logger);
}
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Warning, "Unable to apply configured form options since the request form has already been read.", EventName = "CannotApplyRequestFormLimits")]
public static partial void CannotApplyRequestFormLimits(ILogger logger);

[LoggerMessage(2, LogLevel.Debug, "Applied the configured form options on the current request.", EventName = "AppliedRequestFormLimits")]
public static partial void AppliedRequestFormLimits(ILogger logger);

[LoggerMessage(4, LogLevel.Debug, "Execution of filter {OverriddenFilter} is preempted by filter {OverridingFilter} which is the most effective filter implementing policy {FilterPolicy}.", EventName = "NotMostEffectiveFilter")]
public static partial void NotMostEffectiveFilter(ILogger logger, Type overriddenFilter, Type overridingFilter, Type filterPolicy);
}
}
25 changes: 20 additions & 5 deletions src/Mvc/Mvc.Core/src/Filters/RequestSizeLimitFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters;
/// A filter that sets the <see cref="IHttpMaxRequestBodySizeFeature.MaxRequestBodySize"/>
/// to the specified <see cref="Bytes"/>.
/// </summary>
internal class RequestSizeLimitFilter : IAuthorizationFilter, IRequestSizePolicy
internal partial class RequestSizeLimitFilter : IAuthorizationFilter, IRequestSizePolicy
{
private readonly ILogger _logger;

Expand Down Expand Up @@ -41,24 +41,39 @@ public void OnAuthorization(AuthorizationFilterContext context)
var effectivePolicy = context.FindEffectivePolicy<IRequestSizePolicy>();
if (effectivePolicy != null && effectivePolicy != this)
{
_logger.NotMostEffectiveFilter(GetType(), effectivePolicy.GetType(), typeof(IRequestSizePolicy));
Log.NotMostEffectiveFilter(_logger, GetType(), effectivePolicy.GetType(), typeof(IRequestSizePolicy));
return;
}

var maxRequestBodySizeFeature = context.HttpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();

if (maxRequestBodySizeFeature == null)
{
_logger.FeatureNotFound();
Log.FeatureNotFound(_logger);
}
else if (maxRequestBodySizeFeature.IsReadOnly)
{
_logger.FeatureIsReadOnly();
Log.FeatureIsReadOnly(_logger);
}
else
{
maxRequestBodySizeFeature.MaxRequestBodySize = Bytes;
_logger.MaxRequestBodySizeSet(Bytes.ToString(CultureInfo.InvariantCulture));
Log.MaxRequestBodySizeSet(_logger, Bytes.ToString(CultureInfo.InvariantCulture));
}
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Warning, "A request body size limit could not be applied. This server does not support the IHttpRequestBodySizeFeature.", EventName = "FeatureNotFound")]
public static partial void FeatureNotFound(ILogger logger);

[LoggerMessage(2, LogLevel.Warning, "A request body size limit could not be applied. The IHttpRequestBodySizeFeature for the server is read-only.", EventName = "FeatureIsReadOnly")]
public static partial void FeatureIsReadOnly(ILogger logger);

[LoggerMessage(3, LogLevel.Debug, "The maximum request body size has been set to {RequestSize}.", EventName = "MaxRequestBodySizeSet")]
public static partial void MaxRequestBodySizeSet(ILogger logger, string requestSize);

[LoggerMessage(4, LogLevel.Debug, "Execution of filter {OverriddenFilter} is preempted by filter {OverridingFilter} which is the most effective filter implementing policy {FilterPolicy}.", EventName = "NotMostEffectiveFilter")]
public static partial void NotMostEffectiveFilter(ILogger logger, Type overriddenFilter, Type overridingFilter, Type filterPolicy);
}
}
10 changes: 8 additions & 2 deletions src/Mvc/Mvc.Core/src/Filters/ResponseCacheFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters;
/// <summary>
/// An <see cref="IActionFilter"/> which sets the appropriate headers related to response caching.
/// </summary>
internal class ResponseCacheFilter : IActionFilter, IResponseCacheFilter
internal partial class ResponseCacheFilter : IActionFilter, IResponseCacheFilter
{
private readonly ResponseCacheFilterExecutor _executor;
private readonly ILogger _logger;
Expand Down Expand Up @@ -91,7 +91,7 @@ public void OnActionExecuting(ActionExecutingContext context)
var effectivePolicy = context.FindEffectivePolicy<IResponseCacheFilter>();
if (effectivePolicy != null && effectivePolicy != this)
{
_logger.NotMostEffectiveFilter(GetType(), effectivePolicy.GetType(), typeof(IResponseCacheFilter));
Log.NotMostEffectiveFilter(_logger, GetType(), effectivePolicy.GetType(), typeof(IResponseCacheFilter));
return;
}

Expand All @@ -102,4 +102,10 @@ public void OnActionExecuting(ActionExecutingContext context)
public void OnActionExecuted(ActionExecutedContext context)
{
}

private static partial class Log
{
[LoggerMessage(4, LogLevel.Debug, "Execution of filter {OverriddenFilter} is preempted by filter {OverridingFilter} which is the most effective filter implementing policy {FilterPolicy}.", EventName = "NotMostEffectiveFilter")]
public static partial void NotMostEffectiveFilter(ILogger logger, Type overriddenFilter, Type overridingFilter, Type filterPolicy);
}
}
20 changes: 16 additions & 4 deletions src/Mvc/Mvc.Core/src/Formatters/FormatFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters;
/// A filter that will use the format value in the route data or query string to set the content type on an
/// <see cref="ObjectResult"/> returned from an action.
/// </summary>
public class FormatFilter : IFormatFilter, IResourceFilter, IResultFilter
public partial class FormatFilter : IFormatFilter, IResourceFilter, IResultFilter
{
private readonly MvcOptions _options;
private readonly ILogger _logger;
Expand Down Expand Up @@ -82,7 +82,7 @@ public void OnResourceExecuting(ResourceExecutingContext context)
var contentType = _options.FormatterMappings.GetMediaTypeMappingForFormat(format);
if (contentType == null)
{
_logger.UnsupportedFormatFilterContentType(format);
Log.UnsupportedFormatFilterContentType(_logger, format);

// no contentType exists for the format, return 404
context.Result = new NotFoundResult();
Expand All @@ -100,7 +100,7 @@ public void OnResourceExecuting(ResourceExecutingContext context)
// Check if support is adequate for requested media type.
if (supportedMediaTypes.Count == 0)
{
_logger.ActionDoesNotExplicitlySpecifyContentTypes();
Log.ActionDoesNotExplicitlySpecifyContentTypes(_logger);
return;
}

Expand Down Expand Up @@ -163,7 +163,7 @@ public void OnResultExecuting(ResultExecutingContext context)
if (objectResult.ContentTypes.Count == 1 ||
!string.IsNullOrEmpty(context.HttpContext.Response.ContentType))
{
_logger.CannotApplyFormatFilterContentType(format);
Log.CannotApplyFormatFilterContentType(_logger, format);
return;
}

Expand All @@ -179,4 +179,16 @@ public void OnResultExecuting(ResultExecutingContext context)
public void OnResultExecuted(ResultExecutedContext context)
{
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Debug, "Could not find a media type for the format '{FormatFilterContentType}'.", EventName = "UnsupportedFormatFilterContentType")]
public static partial void UnsupportedFormatFilterContentType(ILogger logger, string formatFilterContentType);

[LoggerMessage(3, LogLevel.Debug, "Cannot apply content type '{FormatFilterContentType}' to the response as current action had explicitly set a preferred content type.", EventName = "CannotApplyFormatFilterContentType")]
public static partial void CannotApplyFormatFilterContentType(ILogger logger, string formatFilterContentType);

[LoggerMessage(5, LogLevel.Debug, "Current action does not explicitly specify any content types for the response.", EventName = "ActionDoesNotExplicitlySpecifyContentTypes")]
public static partial void ActionDoesNotExplicitlySpecifyContentTypes(ILogger logger);
}
}
17 changes: 13 additions & 4 deletions src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure;
/// <summary>
/// A default <see cref="IActionSelector"/> implementation.
/// </summary>
internal class ActionSelector : IActionSelector
internal partial class ActionSelector : IActionSelector
{
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
private readonly ActionConstraintCache _actionConstraintCache;
Expand Down Expand Up @@ -108,8 +108,7 @@ public IReadOnlyList<ActionDescriptor> SelectCandidates(RouteContext context)
var actionNames = string.Join(
Environment.NewLine,
finalMatches.Select(a => a.DisplayName));

_logger.AmbiguousActions(actionNames);
Log.AmbiguousActions(_logger, actionNames);

var message = Resources.FormatDefaultActionSelector_AmbiguousActions(
Environment.NewLine,
Expand Down Expand Up @@ -216,7 +215,8 @@ public IReadOnlyList<ActionDescriptor> SelectCandidates(RouteContext context)
if (!constraint.Accept(constraintContext))
{
isMatch = false;
_logger.ConstraintMismatch(
Log.ConstraintMismatch(
_logger,
candidate.Action.DisplayName,
candidate.Action.Id,
constraint);
Expand Down Expand Up @@ -256,4 +256,13 @@ public IReadOnlyList<ActionDescriptor> SelectCandidates(RouteContext context)
return EvaluateActionConstraintsCore(context, actionsWithoutConstraint, order);
}
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Error, "Request matched multiple actions resulting in ambiguity. Matching actions: {AmbiguousActions}", EventName = "AmbiguousActions")]
public static partial void AmbiguousActions(ILogger logger, string ambiguousActions);

[LoggerMessage(2, LogLevel.Debug, "Action '{ActionName}' with id '{ActionId}' did not match the constraint '{ActionConstraint}'", EventName = "ConstraintMismatch")]
public static partial void ConstraintMismatch(ILogger logger, string? actionName, string actionId, IActionConstraint actionConstraint);
}
}
10 changes: 8 additions & 2 deletions src/Mvc/Mvc.Core/src/Infrastructure/ContentResultExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure;
/// <summary>
/// A <see cref="IActionResultExecutor{ContentResult}"/> that is responsible for <see cref="ContentResult"/>
/// </summary>
public class ContentResultExecutor : IActionResultExecutor<ContentResult>
public partial class ContentResultExecutor : IActionResultExecutor<ContentResult>
{
private const string DefaultContentType = "text/plain; charset=utf-8";
private readonly ILogger<ContentResultExecutor> _logger;
Expand Down Expand Up @@ -60,7 +60,7 @@ public virtual async Task ExecuteAsync(ActionContext context, ContentResult resu
response.StatusCode = result.StatusCode.Value;
}

_logger.ContentResultExecuting(resolvedContentType);
Log.ContentResultExecuting(_logger, resolvedContentType);

if (result.Content != null)
{
Expand All @@ -78,4 +78,10 @@ public virtual async Task ExecuteAsync(ActionContext context, ContentResult resu
}
}
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Information, "Executing ContentResult with HTTP Response ContentType of {ContentType}", EventName = "ContentResultExecuting")]
public static partial void ContentResultExecuting(ILogger logger, string contentType);
}
}
Loading