Reorganize logging, move more types to internal

This commit is contained in:
Ryan Nowak 2016-01-24 17:24:34 -08:00
parent 72d1c49575
commit a276169693
62 changed files with 743 additions and 1062 deletions

View File

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

View File

@ -4,10 +4,9 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Mvc

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

View File

@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;

View File

@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Internal;

View File

@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Logging;

View File

@ -6,6 +6,11 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Internal
@ -21,6 +26,38 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private static readonly Action<ILogger, string, Exception> _contentResultExecuting;
private static readonly Action<ILogger, string, string[], ModelValidationState, Exception> _actionMethodExecuting;
private static readonly Action<ILogger, string, string, Exception> _actionMethodExecuted;
private static readonly Action<ILogger, string, Exception> _ambiguousActions;
private static readonly Action<ILogger, string, string, IActionConstraint, Exception> _constraintMismatch;
private static readonly Action<ILogger, string, Exception> _fileResultExecuting;
private static readonly Action<ILogger, object, Exception> _authorizationFailure;
private static readonly Action<ILogger, object, Exception> _resourceFilterShortCircuit;
private static readonly Action<ILogger, object, Exception> _actionFilterShortCircuit;
private static readonly Action<ILogger, object, Exception> _exceptionFilterShortCircuit;
private static readonly Action<ILogger, string[], Exception> _resultExecuting;
private static readonly Action<ILogger, int, Exception> _httpStatusCodeResultExecuting;
private static readonly Action<ILogger, string, Exception> _localRedirectResultExecuting;
private static readonly Action<ILogger, string, Exception> _objectResultExecuting;
private static readonly Action<ILogger, string, Exception> _noFormatter;
private static readonly Action<ILogger, IOutputFormatter, string, Exception> _formatterSelected;
private static readonly Action<ILogger, string, Exception> _skippedContentNegotiation;
private static readonly Action<ILogger, string, Exception> _noAcceptForNegotiation;
private static readonly Action<ILogger, IEnumerable<MediaTypeSegmentWithQuality>, Exception> _noFormatterFromNegotiation;
private static readonly Action<ILogger, string, Exception> _redirectResultExecuting;
private static readonly Action<ILogger, string, Exception> _redirectToActionResultExecuting;
private static readonly Action<ILogger, string, string, Exception> _redirectToRouteResultExecuting;
static MvcCoreLoggerExtensions()
{
_actionExecuting = LoggerMessage.Define<string>(
@ -42,6 +79,111 @@ namespace Microsoft.AspNetCore.Mvc.Internal
LogLevel.Information,
1,
"Executing ContentResult with HTTP Response ContentType of {ContentType}");
_actionMethodExecuting = LoggerMessage.Define<string, string[], ModelValidationState>(
LogLevel.Information,
1,
"Executing action method {ActionName} with arguments ({Arguments}) - ModelState is {ValidationState}'");
_actionMethodExecuted = LoggerMessage.Define<string, string>(
LogLevel.Debug,
2,
"Executed action method {ActionName}, returned result {ActionResult}.'");
_ambiguousActions = LoggerMessage.Define<string>(
LogLevel.Error,
1,
"Request matched multiple actions resulting in ambiguity. Matching actions: {AmbiguousActions}");
_constraintMismatch = LoggerMessage.Define<string, string, IActionConstraint>(
LogLevel.Debug,
2,
"Action '{ActionName}' with id '{ActionId}' did not match the constraint '{ActionConstraint}'");
_fileResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing FileResult, sending file as {FileDownloadName}");
_authorizationFailure = LoggerMessage.Define<object>(
LogLevel.Warning,
1,
"Authorization failed for the request at filter '{AuthorizationFilter}'.");
_resourceFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
2,
"Request was short circuited at resource filter '{ResourceFilter}'.");
_actionFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
3,
"Request was short circuited at action filter '{ActionFilter}'.");
_exceptionFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
4,
"Request was short circuited at exception filter '{ExceptionFilter}'.");
_resultExecuting = LoggerMessage.Define<string[]>(
LogLevel.Information,
eventId: 1,
formatString: $"Executing {nameof(ForbidResult)} with authentication schemes ({{Schemes}}).");
_httpStatusCodeResultExecuting = LoggerMessage.Define<int>(
LogLevel.Information,
1,
"Executing HttpStatusCodeResult, setting HTTP status code {StatusCode}");
_localRedirectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing LocalRedirectResult, redirecting to {Destination}.");
_noFormatter = LoggerMessage.Define<string>(
LogLevel.Warning,
1,
"No output formatter was found for content type '{ContentType}' to write the response.");
_objectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ObjectResult, writing value {Value}.");
_formatterSelected = LoggerMessage.Define<IOutputFormatter, string>(
LogLevel.Debug,
2,
"Selected output formatter '{OutputFormatter}' and content type '{ContentType}' to write the response.");
_skippedContentNegotiation = LoggerMessage.Define<string>(
LogLevel.Debug,
3,
"Skipped content negotiation as content type '{ContentType}' is explicitly set for the response.");
_noAcceptForNegotiation = LoggerMessage.Define<string>(
LogLevel.Debug,
4,
"No information found on request to perform content negotiation.");
_noFormatterFromNegotiation = LoggerMessage.Define<IEnumerable<MediaTypeSegmentWithQuality>>(
LogLevel.Debug,
5,
"Could not find an output formatter based on content negotiation. Accepted types were ({AcceptTypes})");
_redirectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing RedirectResult, redirecting to {Destination}.");
_redirectToActionResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing RedirectResult, redirecting to {Destination}.");
_redirectToRouteResultExecuting = LoggerMessage.Define<string, string>(
LogLevel.Information,
1,
"Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}.");
}
public static IDisposable ActionScope(this ILogger logger, ActionDescriptor action)
@ -81,6 +223,151 @@ namespace Microsoft.AspNetCore.Mvc.Internal
_contentResultExecuting(logger, contentType, null);
}
public static void ActionMethodExecuting(this ILogger logger, ActionExecutingContext context, object[] arguments)
{
if (logger.IsEnabled(LogLevel.Information))
{
var actionName = context.ActionDescriptor.DisplayName;
string[] convertedArguments;
if (arguments == null)
{
convertedArguments = null;
}
else
{
convertedArguments = new string[arguments.Length];
for (var i = 0; i < arguments.Length; i++)
{
convertedArguments[i] = Convert.ToString(arguments[i]);
}
}
var validationState = context.ModelState.ValidationState;
_actionMethodExecuting(logger, actionName, convertedArguments, validationState, null);
}
}
public static void ActionMethodExecuted(this ILogger logger, ActionExecutingContext context, IActionResult result)
{
var actionName = context.ActionDescriptor.DisplayName;
_actionMethodExecuted(logger, actionName, Convert.ToString(result), null);
}
public static void AmbiguousActions(this ILogger logger, string actionNames)
{
_ambiguousActions(logger, actionNames, null);
}
public static void ConstraintMismatch(
this ILogger logger,
string actionName,
string actionId,
IActionConstraint actionConstraint)
{
_constraintMismatch(logger, actionName, actionId, actionConstraint, null);
}
public static void FileResultExecuting(this ILogger logger, string fileDownloadName)
{
_fileResultExecuting(logger, fileDownloadName, null);
}
public static void AuthorizationFailure(
this ILogger logger,
IFilterMetadata filter)
{
_authorizationFailure(logger, filter, null);
}
public static void ResourceFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_resourceFilterShortCircuit(logger, filter, null);
}
public static void ExceptionFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_exceptionFilterShortCircuit(logger, filter, null);
}
public static void ActionFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_actionFilterShortCircuit(logger, filter, null);
}
public static void ForbidResultExecuting(this ILogger logger, IList<string> authenticationSchemes)
{
_resultExecuting(logger, authenticationSchemes.ToArray(), null);
}
public static void HttpStatusCodeResultExecuting(this ILogger logger, int statusCode)
{
_httpStatusCodeResultExecuting(logger, statusCode, null);
}
public static void LocalRedirectResultExecuting(this ILogger logger, string destination)
{
_localRedirectResultExecuting(logger, destination, null);
}
public static void ObjectResultExecuting(this ILogger logger, object value)
{
_objectResultExecuting(logger, Convert.ToString(value), null);
}
public static void NoFormatter(
this ILogger logger,
OutputFormatterWriteContext formatterContext)
{
_noFormatter(logger, Convert.ToString(formatterContext.ContentType), null);
}
public static void FormatterSelected(
this ILogger logger,
IOutputFormatter outputFormatter,
OutputFormatterWriteContext context)
{
var contentType = Convert.ToString(context.ContentType);
_formatterSelected(logger, outputFormatter, contentType, null);
}
public static void SkippedContentNegotiation(this ILogger logger, string contentType)
{
_skippedContentNegotiation(logger, contentType, null);
}
public static void NoAcceptForNegotiation(this ILogger logger)
{
_noAcceptForNegotiation(logger, null, null);
}
public static void NoFormatterFromNegotiation(this ILogger logger, IList<MediaTypeSegmentWithQuality> acceptTypes)
{
_noFormatterFromNegotiation(logger, acceptTypes, null);
}
public static void RedirectResultExecuting(this ILogger logger, string destination)
{
_redirectResultExecuting(logger, destination, null);
}
public static void RedirectToActionResultExecuting(this ILogger logger, string destination)
{
_redirectToActionResultExecuting(logger, destination, null);
}
public static void RedirectToRouteResultExecuting(this ILogger logger, string destination, string routeName)
{
_redirectToRouteResultExecuting(logger, destination, routeName, null);
}
private class ActionLogScope : ILogValues
{
private readonly ActionDescriptor _action;

View File

@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Tree;
using Microsoft.Extensions.DependencyInjection;

View File

@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;

View File

@ -3,7 +3,7 @@
using System;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

View File

@ -1,61 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class ControllerActionInvokerLoggerExtensions
{
private static readonly Action<ILogger, string, string[], ModelValidationState, Exception> _actionMethodExecuting;
private static readonly Action<ILogger, string, string, Exception> _actionMethodExecuted;
static ControllerActionInvokerLoggerExtensions()
{
_actionMethodExecuting = LoggerMessage.Define<string, string[], ModelValidationState>(
LogLevel.Information,
1,
"Executing action method {ActionName} with arguments ({Arguments}) - ModelState is {ValidationState}'");
_actionMethodExecuted = LoggerMessage.Define<string, string>(
LogLevel.Debug,
2,
"Executed action method {ActionName}, returned result {ActionResult}.'");
}
public static void ActionMethodExecuting(this ILogger logger, ActionExecutingContext context, object[] arguments)
{
if (logger.IsEnabled(LogLevel.Information))
{
var actionName = context.ActionDescriptor.DisplayName;
string[] convertedArguments;
if (arguments == null)
{
convertedArguments = null;
}
else
{
convertedArguments = new string[arguments.Length];
for (var i = 0; i < arguments.Length; i++)
{
convertedArguments[i] = Convert.ToString(arguments[i]);
}
}
var validationState = context.ModelState.ValidationState;
_actionMethodExecuting(logger, actionName, convertedArguments, validationState, null);
}
}
public static void ActionMethodExecuted(this ILogger logger, ActionExecutingContext context, IActionResult result)
{
var actionName = context.ActionDescriptor.DisplayName;
_actionMethodExecuted(logger, actionName, Convert.ToString(result), null);
}
}
}

View File

@ -1,41 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class DefaultActionSelectorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _ambiguousActions;
private static readonly Action<ILogger, string, string, IActionConstraint, Exception> _constraintMismatch;
static DefaultActionSelectorLoggerExtensions()
{
_ambiguousActions = LoggerMessage.Define<string>(
LogLevel.Error,
1,
"Request matched multiple actions resulting in ambiguity. Matching actions: {AmbiguousActions}");
_constraintMismatch = LoggerMessage.Define<string, string, IActionConstraint>(
LogLevel.Debug,
2,
"Action '{ActionName}' with id '{ActionId}' did not match the constraint '{ActionConstraint}'");
}
public static void AmbiguousActions(this ILogger logger, string actionNames)
{
_ambiguousActions(logger, actionNames, null);
}
public static void ConstraintMismatch(
this ILogger logger,
string actionName,
string actionId,
IActionConstraint actionConstraint)
{
_constraintMismatch(logger, actionName, actionId, actionConstraint, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class FileResultLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _fileResultExecuting;
static FileResultLoggerExtensions()
{
_fileResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing FileResult, sending file as {FileDownloadName}");
}
public static void FileResultExecuting(this ILogger logger, string fileDownloadName)
{
_fileResultExecuting(logger, fileDownloadName, null);
}
}
}

View File

@ -1,65 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class FilterActionInvokerLoggerExtensions
{
private static readonly Action<ILogger, object, Exception> _authorizationFailure;
private static readonly Action<ILogger, object, Exception> _resourceFilterShortCircuit;
private static readonly Action<ILogger, object, Exception> _actionFilterShortCircuit;
private static readonly Action<ILogger, object, Exception> _exceptionFilterShortCircuit;
static FilterActionInvokerLoggerExtensions()
{
_authorizationFailure = LoggerMessage.Define<object>(
LogLevel.Warning,
1,
"Authorization failed for the request at filter '{AuthorizationFilter}'.");
_resourceFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
2,
"Request was short circuited at resource filter '{ResourceFilter}'.");
_actionFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
3,
"Request was short circuited at action filter '{ActionFilter}'.");
_exceptionFilterShortCircuit = LoggerMessage.Define<object>(
LogLevel.Debug,
4,
"Request was short circuited at exception filter '{ExceptionFilter}'.");
}
public static void AuthorizationFailure(
this ILogger logger,
IFilterMetadata filter)
{
_authorizationFailure(logger, filter, null);
}
public static void ResourceFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_resourceFilterShortCircuit(logger, filter, null);
}
public static void ExceptionFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_exceptionFilterShortCircuit(logger, filter, null);
}
public static void ActionFilterShortCircuited(
this ILogger logger,
IFilterMetadata filter)
{
_actionFilterShortCircuit(logger, filter, null);
}
}
}

View File

@ -1,24 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class ForbidResultLoggerExtensions
{
private static readonly Action<ILogger, string[], Exception> _resultExecuting =
LoggerMessage.Define<string[]>(
LogLevel.Information,
eventId: 1,
formatString: $"Executing {nameof(ForbidResult)} with authentication schemes ({{Schemes}}).");
public static void ForbidResultExecuting(this ILogger logger, IList<string> authenticationSchemes)
{
_resultExecuting(logger, authenticationSchemes.ToArray(), null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class HttpStatusCodeLoggerExtensions
{
private static readonly Action<ILogger, int, Exception> _httpStatusCodeResultExecuting;
static HttpStatusCodeLoggerExtensions()
{
_httpStatusCodeResultExecuting = LoggerMessage.Define<int>(
LogLevel.Information,
1,
"Executing HttpStatusCodeResult, setting HTTP status code {StatusCode}");
}
public static void HttpStatusCodeResultExecuting(this ILogger logger, int statusCode)
{
_httpStatusCodeResultExecuting(logger, statusCode, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class LocalRedirectResultLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _localRedirectResultExecuting;
static LocalRedirectResultLoggerExtensions()
{
_localRedirectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing LocalRedirectResult, redirecting to {Destination}.");
}
public static void LocalRedirectResultExecuting(this ILogger logger, string destination)
{
_localRedirectResultExecuting(logger, destination, null);
}
}
}

View File

@ -1,85 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class ObjectResultExecutorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _objectResultExecuting;
private static readonly Action<ILogger, string, Exception> _noFormatter;
private static readonly Action<ILogger, IOutputFormatter, string, Exception> _formatterSelected;
private static readonly Action<ILogger, string, Exception> _skippedContentNegotiation;
private static readonly Action<ILogger, string, Exception> _noAcceptForNegotiation;
private static readonly Action<ILogger, IEnumerable<MediaTypeSegmentWithQuality>, Exception> _noFormatterFromNegotiation;
static ObjectResultExecutorLoggerExtensions()
{
_noFormatter = LoggerMessage.Define<string>(
LogLevel.Warning,
1,
"No output formatter was found for content type '{ContentType}' to write the response.");
_objectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ObjectResult, writing value {Value}.");
_formatterSelected = LoggerMessage.Define<IOutputFormatter, string>(
LogLevel.Debug,
2,
"Selected output formatter '{OutputFormatter}' and content type '{ContentType}' to write the response.");
_skippedContentNegotiation = LoggerMessage.Define<string>(
LogLevel.Debug,
3,
"Skipped content negotiation as content type '{ContentType}' is explicitly set for the response.");
_noAcceptForNegotiation = LoggerMessage.Define<string>(
LogLevel.Debug,
4,
"No information found on request to perform content negotiation.");
_noFormatterFromNegotiation = LoggerMessage.Define<IEnumerable<MediaTypeSegmentWithQuality>>(
LogLevel.Debug,
5,
"Could not find an output formatter based on content negotiation. Accepted types were ({AcceptTypes})");
}
public static void ObjectResultExecuting(this ILogger logger, object value)
{
_objectResultExecuting(logger, Convert.ToString(value), null);
}
public static void NoFormatter(
this ILogger logger,
OutputFormatterWriteContext formatterContext)
{
_noFormatter(logger, Convert.ToString(formatterContext.ContentType), null);
}
public static void FormatterSelected(
this ILogger logger,
IOutputFormatter outputFormatter,
OutputFormatterWriteContext context)
{
var contentType = Convert.ToString(context.ContentType);
_formatterSelected(logger, outputFormatter, contentType, null);
}
public static void SkippedContentNegotiation(this ILogger logger, string contentType)
{
_skippedContentNegotiation(logger, contentType, null);
}
public static void NoAcceptForNegotiation(this ILogger logger)
{
_noAcceptForNegotiation(logger, null, null);
}
public static void NoFormatterFromNegotiation(this ILogger logger, IList<MediaTypeSegmentWithQuality> acceptTypes)
{
_noFormatterFromNegotiation(logger, acceptTypes, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class RedirectResultLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _redirectResultExecuting;
static RedirectResultLoggerExtensions()
{
_redirectResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing RedirectResult, redirecting to {Destination}.");
}
public static void RedirectResultExecuting(this ILogger logger, string destination)
{
_redirectResultExecuting(logger, destination, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class RedirectToActionResultLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _redirectToActionResultExecuting;
static RedirectToActionResultLoggerExtensions()
{
_redirectToActionResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing RedirectResult, redirecting to {Destination}.");
}
public static void RedirectToActionResultExecuting(this ILogger logger, string destination)
{
_redirectToActionResultExecuting(logger, destination, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class RedirectToRouteResultLoggerExtensions
{
private static readonly Action<ILogger, string, string, Exception> _redirectToRouteResultExecuting;
static RedirectToRouteResultLoggerExtensions()
{
_redirectToRouteResultExecuting = LoggerMessage.Define<string, string>(
LogLevel.Information,
1,
"Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}.");
}
public static void RedirectToRouteResultExecuting(this ILogger logger, string destination, string routeName)
{
_redirectToRouteResultExecuting(logger, destination, routeName, null);
}
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class ViewResultExecutorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _viewFound;
private static readonly Action<ILogger, string, IEnumerable<string>, Exception> _viewNotFound;
static ViewResultExecutorLoggerExtensions()
{
_viewFound = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"The view '{ViewName}' was found.");
_viewNotFound = LoggerMessage.Define<string, IEnumerable<string>>(
LogLevel.Error,
2,
"The view '{ViewName}' was not found. Searched locations: {SearchedViewLocations}");
}
public static void ViewFound(this ILogger logger, string viewName)
{
_viewFound(logger, viewName, null);
}
public static void ViewNotFound(
this ILogger logger,
string viewName,
IEnumerable<string> searchedLocations)
{
_viewNotFound(logger, viewName, searchedLocations, null);
}
}
}

View File

@ -3,7 +3,7 @@
using System;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.DependencyInjection;

View File

@ -3,7 +3,7 @@
using System;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;

View File

@ -3,7 +3,7 @@
using System;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;

View File

@ -5,13 +5,12 @@ using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc.Infrastructure
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
/// <summary>
/// Executes a <see cref="JsonResult"/> to write to the response.

View File

@ -4,7 +4,7 @@
using Microsoft.Extensions.ObjectPool;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc.Formatters.Internal
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
/// <summary>
/// <see cref="IPooledObjectPolicy{T}"/> for <see cref="JsonSerializer"/>.

View File

@ -3,7 +3,7 @@
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
internal class MediaTypeHeaderValues
{

View File

@ -0,0 +1,38 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
internal static class MvcJsonLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _jsonInputFormatterCrashed;
private static readonly Action<ILogger, string, Exception> _jsonResultExecuting;
static MvcJsonLoggerExtensions()
{
_jsonInputFormatterCrashed = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"JSON input formatter threw an exception.");
_jsonResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing JsonResult, writing value {Value}.");
}
public static void JsonInputException(this ILogger logger, Exception exception)
{
_jsonInputFormatterCrashed(logger, exception.ToString(), exception);
}
public static void JsonResultExecuting(this ILogger logger, object value)
{
_jsonResultExecuting(logger, Convert.ToString(value), null);
}
}
}

View File

@ -3,7 +3,7 @@
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
/// <summary>
/// Helper class which provides <see cref="JsonSerializerSettings"/>.

View File

@ -4,10 +4,7 @@
using System;
using System.Buffers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Logging;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;

View File

@ -6,7 +6,7 @@ using System.Buffers;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Newtonsoft.Json;

View File

@ -3,9 +3,8 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc

View File

@ -1,23 +0,0 @@
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Logging
{
internal static class JsonInputFormatterLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _jsonInputFormatterCrashed;
static JsonInputFormatterLoggerExtensions()
{
_jsonInputFormatterCrashed = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"JSON input formatter threw an exception.");
}
public static void JsonInputException(this ILogger logger, Exception exception)
{
_jsonInputFormatterCrashed(logger, exception.ToString(), exception);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
internal static class JsonResultExecutorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _jsonResultExecuting;
static JsonResultExecutorLoggerExtensions()
{
_jsonResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing JsonResult, writing value {Value}.");
}
public static void JsonResultExecuting(this ILogger logger, object value)
{
_jsonResultExecuting(logger, Convert.ToString(value), null);
}
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc

View File

@ -7,12 +7,11 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.CodeGenerators;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{

View File

@ -14,7 +14,6 @@ using System.Runtime.Loader;
#endif
using System.Runtime.Versioning;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

View File

@ -0,0 +1,98 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
{
internal static class MvcRazorLoggerExtensions
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private static readonly Action<ILogger, string, Exception> _generatedCodeToAssemblyCompilationStart;
private static readonly Action<ILogger, string, double, Exception> _generatedCodeToAssemblyCompilationEnd;
private static readonly Action<ILogger, string, Exception> _razorFileToCodeCompilationStart;
private static readonly Action<ILogger, string, double, Exception> _razorFileToCodeCompilationEnd;
private static readonly Action<ILogger, string, string, Exception> _viewLookupCacheMiss;
private static readonly Action<ILogger, string, string, Exception> _viewLookupCacheHit;
static MvcRazorLoggerExtensions()
{
_razorFileToCodeCompilationStart = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"Code generation for the Razor file at '{FilePath}' started.");
_razorFileToCodeCompilationEnd = LoggerMessage.Define<string, double>(
LogLevel.Debug,
2,
"Code generation for the Razor file at '{FilePath}' completed in {ElapsedMilliseconds}ms.");
_viewLookupCacheMiss = LoggerMessage.Define<string, string>(
LogLevel.Debug,
1,
"View lookup cache miss for view '{ViewName}' in controller '{ControllerName}'.");
_viewLookupCacheHit = LoggerMessage.Define<string, string>(
LogLevel.Debug,
2,
"View lookup cache hit for view '{ViewName}' in controller '{ControllerName}'.");
_generatedCodeToAssemblyCompilationStart = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"Compilation of the generated code for the Razor file at '{FilePath}' started.");
_generatedCodeToAssemblyCompilationEnd = LoggerMessage.Define<string, double>(
LogLevel.Debug,
2,
"Compilation of the generated code for the Razor file at '{FilePath}' completed in {ElapsedMilliseconds}ms.");
}
public static void RazorFileToCodeCompilationStart(this ILogger logger, string filePath)
{
_razorFileToCodeCompilationStart(logger, filePath, null);
}
public static void RazorFileToCodeCompilationEnd(this ILogger logger, string filePath, long startTimestamp)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_razorFileToCodeCompilationEnd(logger, filePath, elapsed.TotalMilliseconds, null);
}
}
public static void ViewLookupCacheMiss(this ILogger logger, string viewName, string controllerName)
{
_viewLookupCacheMiss(logger, viewName, controllerName, null);
}
public static void ViewLookupCacheHit(this ILogger logger, string viewName, string controllerName)
{
_viewLookupCacheHit(logger, viewName, controllerName, null);
}
public static void GeneratedCodeToAssemblyCompilationStart(this ILogger logger, string filePath)
{
_generatedCodeToAssemblyCompilationStart(logger, filePath, null);
}
public static void GeneratedCodeToAssemblyCompilationEnd(this ILogger logger, string filePath, long startTimestamp)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_generatedCodeToAssemblyCompilationEnd(logger, filePath, elapsed.TotalMilliseconds, null);
}
}
}
}

View File

@ -1,45 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class RazorCompilationServiceLoggerExtensions
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private static readonly Action<ILogger, string, Exception> _razorFileToCodeCompilationStart;
private static readonly Action<ILogger, string, double, Exception> _razorFileToCodeCompilationEnd;
static RazorCompilationServiceLoggerExtensions()
{
_razorFileToCodeCompilationStart = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"Code generation for the Razor file at '{FilePath}' started.");
_razorFileToCodeCompilationEnd = LoggerMessage.Define<string, double>(
LogLevel.Debug,
2,
"Code generation for the Razor file at '{FilePath}' completed in {ElapsedMilliseconds}ms.");
}
public static void RazorFileToCodeCompilationStart(this ILogger logger, string filePath)
{
_razorFileToCodeCompilationStart(logger, filePath, null);
}
public static void RazorFileToCodeCompilationEnd(this ILogger logger, string filePath, long startTimestamp)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_razorFileToCodeCompilationEnd(logger, filePath, elapsed.TotalMilliseconds, null);
}
}
}
}

View File

@ -1,37 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class RazorViewEngineLoggerExtensions
{
private static readonly Action<ILogger, string, string, Exception> _viewLookupCacheMiss;
private static readonly Action<ILogger, string, string, Exception> _viewLookupCacheHit;
static RazorViewEngineLoggerExtensions()
{
_viewLookupCacheMiss = LoggerMessage.Define<string, string>(
LogLevel.Debug,
1,
"View lookup cache miss for view '{ViewName}' in controller '{ControllerName}'.");
_viewLookupCacheHit = LoggerMessage.Define<string, string>(
LogLevel.Debug,
2,
"View lookup cache hit for view '{ViewName}' in controller '{ControllerName}'.");
}
public static void ViewLookupCacheMiss(this ILogger logger, string viewName, string controllerName)
{
_viewLookupCacheMiss(logger, viewName, controllerName, null);
}
public static void ViewLookupCacheHit(this ILogger logger, string viewName, string controllerName)
{
_viewLookupCacheHit(logger, viewName, controllerName, null);
}
}
}

View File

@ -1,45 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class RoslynCompilationServiceLoggerExtensions
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private static readonly Action<ILogger, string, Exception> _generatedCodeToAssemblyCompilationStart;
private static readonly Action<ILogger, string, double, Exception> _generatedCodeToAssemblyCompilationEnd;
static RoslynCompilationServiceLoggerExtensions()
{
_generatedCodeToAssemblyCompilationStart = LoggerMessage.Define<string>(
LogLevel.Debug,
1,
"Compilation of the generated code for the Razor file at '{FilePath}' started.");
_generatedCodeToAssemblyCompilationEnd = LoggerMessage.Define<string, double>(
LogLevel.Debug,
2,
"Compilation of the generated code for the Razor file at '{FilePath}' completed in {ElapsedMilliseconds}ms.");
}
public static void GeneratedCodeToAssemblyCompilationStart(this ILogger logger, string filePath)
{
_generatedCodeToAssemblyCompilationStart(logger, filePath, null);
}
public static void GeneratedCodeToAssemblyCompilationEnd(this ILogger logger, string filePath, long startTimestamp)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_generatedCodeToAssemblyCompilationEnd(logger, filePath, elapsed.TotalMilliseconds, null);
}
}
}
}

View File

@ -7,7 +7,7 @@ using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Caching.Memory;

View File

@ -1,85 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
namespace Microsoft.AspNetCore.Mvc.Diagnostics
{
public static class ViewExecutorDiagnosticSourceExtensions
{
public static void BeforeView(
this DiagnosticSource diagnosticSource,
IView view,
ViewContext viewContext)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.BeforeView"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.BeforeView",
new { view = view, viewContext = viewContext, });
}
}
public static void AfterView(
this DiagnosticSource diagnosticSource,
IView view,
ViewContext viewContext)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.AfterView"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.AfterView",
new { view = view, viewContext = viewContext, });
}
}
public static void ViewFound(
this DiagnosticSource diagnosticSource,
ActionContext actionContext,
bool isMainPage,
PartialViewResult viewResult,
string viewName,
IView view)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.ViewFound"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.ViewFound",
new
{
actionContext = actionContext,
isMainPage = isMainPage,
result = viewResult,
viewName = viewName,
view = view,
});
}
}
public static void ViewNotFound(
this DiagnosticSource diagnosticSource,
ActionContext actionContext,
bool isMainPage,
PartialViewResult viewResult,
string viewName,
IEnumerable<string> searchedLocations)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.ViewNotFound"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.ViewNotFound",
new
{
actionContext = actionContext,
isMainPage = isMainPage,
result = viewResult,
viewName = viewName,
searchedLocations = searchedLocations,
});
}
}
}
}

View File

@ -1,14 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.AspNetCore.Mvc.ViewEngines;
namespace Microsoft.AspNetCore.Mvc.Diagnostics
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
{
public static class ViewComponentDiagnosticSourceExtensions
internal static class MvcViewFeaturesDiagnosticSourceExtensions
{
public static void BeforeViewComponent(
this DiagnosticSource diagnosticSource,
@ -83,5 +84,77 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics
});
}
}
public static void BeforeView(
this DiagnosticSource diagnosticSource,
IView view,
ViewContext viewContext)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.BeforeView"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.BeforeView",
new { view = view, viewContext = viewContext, });
}
}
public static void AfterView(
this DiagnosticSource diagnosticSource,
IView view,
ViewContext viewContext)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.AfterView"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.AfterView",
new { view = view, viewContext = viewContext, });
}
}
public static void ViewFound(
this DiagnosticSource diagnosticSource,
ActionContext actionContext,
bool isMainPage,
PartialViewResult viewResult,
string viewName,
IView view)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.ViewFound"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.ViewFound",
new
{
actionContext = actionContext,
isMainPage = isMainPage,
result = viewResult,
viewName = viewName,
view = view,
});
}
}
public static void ViewNotFound(
this DiagnosticSource diagnosticSource,
ActionContext actionContext,
bool isMainPage,
PartialViewResult viewResult,
string viewName,
IEnumerable<string> searchedLocations)
{
if (diagnosticSource.IsEnabled("Microsoft.AspNetCore.Mvc.ViewNotFound"))
{
diagnosticSource.Write(
"Microsoft.AspNetCore.Mvc.ViewNotFound",
new
{
actionContext = actionContext,
isMainPage = isMainPage,
result = viewResult,
viewName = viewName,
searchedLocations = searchedLocations,
});
}
}
}
}

View File

@ -0,0 +1,219 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
{
internal static class MvcViewFeaturesLoggerExtensions
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private static readonly string[] EmptyArguments = new string[0];
private static readonly Action<ILogger, string, string[], Exception> _viewComponentExecuting;
private static readonly Action<ILogger, string, double, string, Exception> _viewComponentExecuted;
private static readonly Action<ILogger, string, Exception> _partialViewFound;
private static readonly Action<ILogger, string, IEnumerable<string>, Exception> _partialViewNotFound;
private static readonly Action<ILogger, string, Exception> _partialViewResultExecuting;
private static readonly Action<ILogger, string, Exception> _antiforgeryTokenInvalid;
private static readonly Action<ILogger, string, Exception> _viewComponentResultExecuting;
private static readonly Action<ILogger, string, Exception> _viewResultExecuting;
private static readonly Action<ILogger, string, Exception> _viewFound;
private static readonly Action<ILogger, string, IEnumerable<string>, Exception> _viewNotFound;
static MvcViewFeaturesLoggerExtensions()
{
_viewComponentExecuting = LoggerMessage.Define<string, string[]>(
LogLevel.Debug,
1,
"Executing view component {ViewComponentName} with arguments ({Arguments}).");
_viewComponentExecuted = LoggerMessage.Define<string, double, string>(
LogLevel.Debug,
2,
"Executed view component {ViewComponentName} in {ElapsedMilliseconds}ms and returned " +
"{ViewComponentResult}");
_partialViewResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing PartialViewResult, running view at path {Path}.");
_partialViewFound = LoggerMessage.Define<string>(
LogLevel.Debug,
2,
"The partial view '{PartialViewName}' was found.");
_partialViewNotFound = LoggerMessage.Define<string, IEnumerable<string>>(
LogLevel.Error,
3,
"The partial view '{PartialViewName}' was not found. Searched locations: {SearchedViewLocations}");
_antiforgeryTokenInvalid = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Antiforgery token validation failed. {Message}");
_viewComponentResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ViewComponentResult, running {ViewComponentName}.");
_viewResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ViewResult, running view at path {Path}.");
_viewFound = LoggerMessage.Define<string>(
LogLevel.Debug,
2,
"The view '{ViewName}' was found.");
_viewNotFound = LoggerMessage.Define<string, IEnumerable<string>>(
LogLevel.Error,
3,
"The view '{ViewName}' was not found. Searched locations: {SearchedViewLocations}");
}
public static IDisposable ViewComponentScope(this ILogger logger, ViewComponentContext context)
{
return logger.BeginScopeImpl(new ViewComponentLogScope(context.ViewComponentDescriptor));
}
public static void ViewComponentExecuting(
this ILogger logger,
ViewComponentContext context,
object[] arguments)
{
var formattedArguments = GetFormattedArguments(arguments);
_viewComponentExecuting(logger, context.ViewComponentDescriptor.DisplayName, formattedArguments, null);
}
private static string[] GetFormattedArguments(object[] arguments)
{
if (arguments == null || arguments.Length == 0)
{
return EmptyArguments;
}
var formattedArguments = new string[arguments.Length];
for (var i = 0; i < formattedArguments.Length; i++)
{
formattedArguments[i] = Convert.ToString(arguments[i]);
}
return formattedArguments;
}
public static void ViewComponentExecuted(
this ILogger logger,
ViewComponentContext context,
long startTimestamp,
object result)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_viewComponentExecuted(
logger,
context.ViewComponentDescriptor.DisplayName,
elapsed.TotalMilliseconds,
Convert.ToString(result),
null);
}
}
public static void PartialViewFound(
this ILogger logger,
string partialViewName)
{
_partialViewFound(logger, partialViewName, null);
}
public static void PartialViewNotFound(
this ILogger logger,
string partialViewName,
IEnumerable<string> searchedLocations)
{
_partialViewNotFound(logger, partialViewName, searchedLocations, null);
}
public static void PartialViewResultExecuting(this ILogger logger, IView view)
{
_partialViewResultExecuting(logger, view.Path, null);
}
public static void AntiforgeryTokenInvalid(this ILogger logger, string message, Exception exception)
{
_antiforgeryTokenInvalid(logger, message, exception);
}
public static void ViewComponentResultExecuting(this ILogger logger, string viewComponentName)
{
if (logger.IsEnabled(LogLevel.Information))
{
_viewComponentResultExecuting(logger, viewComponentName, null);
}
}
public static void ViewComponentResultExecuting(this ILogger logger, Type viewComponentType)
{
if (logger.IsEnabled(LogLevel.Information))
{
_viewComponentResultExecuting(logger, viewComponentType.Name, null);
}
}
public static void ViewResultExecuting(this ILogger logger, IView view)
{
_viewResultExecuting(logger, view.Path, null);
}
public static void ViewFound(this ILogger logger, string viewName)
{
_viewFound(logger, viewName, null);
}
public static void ViewNotFound(this ILogger logger, string viewName,
IEnumerable<string> searchedLocations)
{
_viewNotFound(logger, viewName, searchedLocations, null);
}
private class ViewComponentLogScope : ILogValues
{
private readonly ViewComponentDescriptor _descriptor;
public ViewComponentLogScope(ViewComponentDescriptor descriptor)
{
_descriptor = descriptor;
}
public IEnumerable<KeyValuePair<string, object>> GetValues()
{
return new KeyValuePair<string, object>[]
{
new KeyValuePair<string, object>("ViewComponentName", _descriptor.DisplayName),
new KeyValuePair<string, object>("ViewComponentId", _descriptor.Id),
};
}
public override string ToString()
{
return _descriptor.DisplayName;
}
}
}
}

View File

@ -7,8 +7,6 @@ using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal

View File

@ -1,113 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Logging
{
public static class DefaultViewComponentInvokerLoggerExtensions
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
private static readonly string[] EmptyArguments =
#if NET451
new string[0];
#else
Array.Empty<string>();
#endif
private static readonly Action<ILogger, string, string[], Exception> _viewComponentExecuting;
private static readonly Action<ILogger, string, double, string, Exception> _viewComponentExecuted;
static DefaultViewComponentInvokerLoggerExtensions()
{
_viewComponentExecuting = LoggerMessage.Define<string, string[]>(
LogLevel.Debug,
1,
"Executing view component {ViewComponentName} with arguments ({Arguments}).");
_viewComponentExecuted = LoggerMessage.Define<string, double, string>(
LogLevel.Debug,
2,
"Executed view component {ViewComponentName} in {ElapsedMilliseconds}ms and returned " +
"{ViewComponentResult}");
}
public static IDisposable ViewComponentScope(this ILogger logger, ViewComponentContext context)
{
return logger.BeginScopeImpl(new ViewComponentLogScope(context.ViewComponentDescriptor));
}
public static void ViewComponentExecuting(
this ILogger logger,
ViewComponentContext context,
object[] arguments)
{
var formattedArguments = GetFormattedArguments(arguments);
_viewComponentExecuting(logger, context.ViewComponentDescriptor.DisplayName, formattedArguments, null);
}
private static string[] GetFormattedArguments(object[] arguments)
{
if (arguments == null || arguments.Length == 0)
{
return EmptyArguments;
}
var formattedArguments = new string[arguments.Length];
for (var i = 0; i < formattedArguments.Length; i++)
{
formattedArguments[i] = Convert.ToString(arguments[i]);
}
return formattedArguments;
}
public static void ViewComponentExecuted(
this ILogger logger,
ViewComponentContext context,
long startTimestamp,
object result)
{
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
if (startTimestamp != 0)
{
var currentTimestamp = Stopwatch.GetTimestamp();
var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp)));
_viewComponentExecuted(
logger,
context.ViewComponentDescriptor.DisplayName,
elapsed.TotalMilliseconds,
Convert.ToString(result),
null);
}
}
private class ViewComponentLogScope : ILogValues
{
private readonly ViewComponentDescriptor _descriptor;
public ViewComponentLogScope(ViewComponentDescriptor descriptor)
{
_descriptor = descriptor;
}
public IEnumerable<KeyValuePair<string, object>> GetValues()
{
return new KeyValuePair<string, object>[]
{
new KeyValuePair<string, object>("ViewComponentName", _descriptor.DisplayName),
new KeyValuePair<string, object>("ViewComponentId", _descriptor.Id),
};
}
public override string ToString()
{
return _descriptor.DisplayName;
}
}
}
}

View File

@ -1,53 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Logging
{
internal static class PartialViewResultExecutorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _partialViewFound;
private static readonly Action<ILogger, string, IEnumerable<string>, Exception> _partialViewNotFound;
private static readonly Action<ILogger, string, Exception> _partialViewResultExecuting;
static PartialViewResultExecutorLoggerExtensions()
{
_partialViewResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing PartialViewResult, running view at path {Path}.");
_partialViewFound = LoggerMessage.Define<string>(
LogLevel.Debug,
2,
"The partial view '{PartialViewName}' was found.");
_partialViewNotFound = LoggerMessage.Define<string, IEnumerable<string>>(
LogLevel.Error,
3,
"The partial view '{PartialViewName}' was not found. Searched locations: {SearchedViewLocations}");
}
public static void PartialViewFound(
this ILogger logger,
string partialViewName)
{
_partialViewFound(logger, partialViewName, null);
}
public static void PartialViewNotFound(
this ILogger logger,
string partialViewName,
IEnumerable<string> searchedLocations)
{
_partialViewNotFound(logger, partialViewName, searchedLocations, null);
}
public static void PartialViewResultExecuting(this ILogger logger, IView view)
{
_partialViewResultExecuting(logger, view.Path, null);
}
}
}

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class ValidateAntiforgeryTokenAuthorizationFilterLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _antiforgeryTokenInvalid;
static ValidateAntiforgeryTokenAuthorizationFilterLoggerExtensions()
{
_antiforgeryTokenInvalid = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Antiforgery token validation failed. {Message}");
}
public static void AntiforgeryTokenInvalid(this ILogger logger, string message, Exception exception)
{
_antiforgeryTokenInvalid(logger, message, exception);
}
}
}

View File

@ -1,37 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class ViewComponentResultLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _viewComponentResultExecuting;
static ViewComponentResultLoggerExtensions()
{
_viewComponentResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ViewComponentResult, running {ViewComponentName}.");
}
public static void ViewComponentResultExecuting(this ILogger logger, string viewComponentName)
{
if (logger.IsEnabled(LogLevel.Information))
{
_viewComponentResultExecuting(logger, viewComponentName, null);
}
}
public static void ViewComponentResultExecuting(this ILogger logger, Type viewComponentType)
{
if (logger.IsEnabled(LogLevel.Information))
{
_viewComponentResultExecuting(logger, viewComponentType.Name, null);
}
}
}
}

View File

@ -1,49 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.Logging
{
public static class ViewResultExecutorLoggerExtensions
{
private static readonly Action<ILogger, string, Exception> _viewResultExecuting;
private static readonly Action<ILogger, string, Exception> _viewFound;
private static readonly Action<ILogger, string, IEnumerable<string>, Exception> _viewNotFound;
static ViewResultExecutorLoggerExtensions()
{
_viewResultExecuting = LoggerMessage.Define<string>(
LogLevel.Information,
1,
"Executing ViewResult, running view at path {Path}.");
_viewFound = LoggerMessage.Define<string>(
LogLevel.Debug,
2,
"The view '{ViewName}' was found.");
_viewNotFound = LoggerMessage.Define<string, IEnumerable<string>>(
LogLevel.Error,
3,
"The view '{ViewName}' was not found. Searched locations: {SearchedViewLocations}");
}
public static void ViewResultExecuting(this ILogger logger, IView view)
{
_viewResultExecuting(logger, view.Path, null);
}
public static void ViewFound(this ILogger logger, string viewName)
{
_viewFound(logger, viewName, null);
}
public static void ViewNotFound(this ILogger logger, string viewName,
IEnumerable<string> searchedLocations)
{
_viewNotFound(logger, viewName, searchedLocations, null);
}
}
}

View File

@ -7,7 +7,6 @@ using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;

View File

@ -7,12 +7,9 @@ using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Logging;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Mvc.ViewComponents

View File

@ -6,10 +6,10 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.ViewComponents

View File

@ -6,11 +6,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Logging;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

View File

@ -5,15 +5,13 @@ using System;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{

View File

@ -7,8 +7,8 @@ using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Logging;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

View File

@ -1,9 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@ -17,7 +15,7 @@ using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Infrastructure
namespace Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
{
public class JsonResultExecutorTest
{

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Logging;

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Testing;