Logging for filters

This commit is contained in:
Kiran Challa 2015-04-21 15:45:45 -07:00
parent 1511ea34a8
commit 687ab258a1
4 changed files with 73 additions and 1 deletions

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.Mvc.Core namespace Microsoft.AspNet.Mvc.Core
{ {
@ -31,6 +32,7 @@ namespace Microsoft.AspNet.Mvc.Core
[NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories, [NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories,
[NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor, [NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor,
[NotNull] ITempDataDictionary tempData, [NotNull] ITempDataDictionary tempData,
[NotNull] ILoggerFactory loggerFactory,
int maxModelValidationErrors) int maxModelValidationErrors)
: base( : base(
actionContext, actionContext,
@ -41,6 +43,7 @@ namespace Microsoft.AspNet.Mvc.Core
modelValidatorProviders, modelValidatorProviders,
valueProviderFactories, valueProviderFactories,
actionBindingContextAccessor, actionBindingContextAccessor,
loggerFactory,
maxModelValidationErrors) maxModelValidationErrors)
{ {
_descriptor = descriptor; _descriptor = descriptor;

View File

@ -6,6 +6,7 @@ using System.Linq;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.Core namespace Microsoft.AspNet.Mvc.Core
@ -23,6 +24,7 @@ namespace Microsoft.AspNet.Mvc.Core
private readonly IScopedInstance<ActionBindingContext> _actionBindingContextAccessor; private readonly IScopedInstance<ActionBindingContext> _actionBindingContextAccessor;
private readonly ITempDataDictionary _tempData; private readonly ITempDataDictionary _tempData;
private readonly int _maxModelValidationErrors; private readonly int _maxModelValidationErrors;
private readonly ILoggerFactory _loggerFactory;
public ControllerActionInvokerProvider( public ControllerActionInvokerProvider(
IControllerFactory controllerFactory, IControllerFactory controllerFactory,
@ -30,7 +32,8 @@ namespace Microsoft.AspNet.Mvc.Core
IControllerActionArgumentBinder argumentBinder, IControllerActionArgumentBinder argumentBinder,
IOptions<MvcOptions> optionsAccessor, IOptions<MvcOptions> optionsAccessor,
IScopedInstance<ActionBindingContext> actionBindingContextAccessor, IScopedInstance<ActionBindingContext> actionBindingContextAccessor,
ITempDataDictionary tempData) ITempDataDictionary tempData,
ILoggerFactory loggerFactory)
{ {
_controllerFactory = controllerFactory; _controllerFactory = controllerFactory;
_filterProviders = filterProviders.OrderBy(item => item.Order).ToArray(); _filterProviders = filterProviders.OrderBy(item => item.Order).ToArray();
@ -43,6 +46,7 @@ namespace Microsoft.AspNet.Mvc.Core
_actionBindingContextAccessor = actionBindingContextAccessor; _actionBindingContextAccessor = actionBindingContextAccessor;
_tempData = tempData; _tempData = tempData;
_maxModelValidationErrors = optionsAccessor.Options.MaxModelValidationErrors; _maxModelValidationErrors = optionsAccessor.Options.MaxModelValidationErrors;
_loggerFactory = loggerFactory;
} }
public int Order public int Order
@ -70,6 +74,7 @@ namespace Microsoft.AspNet.Mvc.Core
_valueProviderFactories, _valueProviderFactories,
_actionBindingContextAccessor, _actionBindingContextAccessor,
_tempData, _tempData,
_loggerFactory,
_maxModelValidationErrors); _maxModelValidationErrors);
} }
} }

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.Mvc.Core namespace Microsoft.AspNet.Mvc.Core
{ {
@ -22,6 +23,7 @@ namespace Microsoft.AspNet.Mvc.Core
private readonly IReadOnlyList<IModelValidatorProvider> _modelValidatorProviders; private readonly IReadOnlyList<IModelValidatorProvider> _modelValidatorProviders;
private readonly IReadOnlyList<IValueProviderFactory> _valueProviderFactories; private readonly IReadOnlyList<IValueProviderFactory> _valueProviderFactories;
private readonly IScopedInstance<ActionBindingContext> _actionBindingContextAccessor; private readonly IScopedInstance<ActionBindingContext> _actionBindingContextAccessor;
private readonly ILogger _logger;
private readonly int _maxModelValidationErrors; private readonly int _maxModelValidationErrors;
private IFilter[] _filters; private IFilter[] _filters;
@ -40,6 +42,17 @@ namespace Microsoft.AspNet.Mvc.Core
private ResultExecutingContext _resultExecutingContext; private ResultExecutingContext _resultExecutingContext;
private ResultExecutedContext _resultExecutedContext; private ResultExecutedContext _resultExecutedContext;
private const string AuthorizationFailureLogMessage =
"Authorization failed for the request at filter '{AuthorizationFilter}'.";
private const string ResourceFilterShortCircuitLogMessage =
"Request was short circuited at resource filter '{ResourceFilter}'.";
private const string ActionFilterShortCircuitLogMessage =
"Request was short circuited at action filter '{ActionFilter}'.";
private const string ExceptionFilterShortCircuitLogMessage =
"Request was short circuited at exception filter '{ExceptionFilter}'.";
private const string ResultFilterShortCircuitLogMessage =
"Request was short circuited at result filter '{ResultFilter}'.";
public FilterActionInvoker( public FilterActionInvoker(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IReadOnlyList<IFilterProvider> filterProviders, [NotNull] IReadOnlyList<IFilterProvider> filterProviders,
@ -49,6 +62,7 @@ namespace Microsoft.AspNet.Mvc.Core
[NotNull] IReadOnlyList<IModelValidatorProvider> modelValidatorProviders, [NotNull] IReadOnlyList<IModelValidatorProvider> modelValidatorProviders,
[NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories, [NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories,
[NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor, [NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor,
[NotNull] ILoggerFactory loggerFactory,
int maxModelValidationErrors) int maxModelValidationErrors)
{ {
ActionContext = actionContext; ActionContext = actionContext;
@ -60,6 +74,7 @@ namespace Microsoft.AspNet.Mvc.Core
_modelValidatorProviders = modelValidatorProviders; _modelValidatorProviders = modelValidatorProviders;
_valueProviderFactories = valueProviderFactories; _valueProviderFactories = valueProviderFactories;
_actionBindingContextAccessor = actionBindingContextAccessor; _actionBindingContextAccessor = actionBindingContextAccessor;
_logger = loggerFactory.CreateLogger<FilterActionInvoker>();
_maxModelValidationErrors = maxModelValidationErrors; _maxModelValidationErrors = maxModelValidationErrors;
} }
@ -190,6 +205,10 @@ namespace Microsoft.AspNet.Mvc.Core
// Only keep going if we don't have a result // Only keep going if we don't have a result
await InvokeAuthorizationFilterAsync(); await InvokeAuthorizationFilterAsync();
} }
else
{
_logger.LogWarning(AuthorizationFailureLogMessage, current.FilterAsync.GetType().FullName);
}
} }
else if (current.Filter != null) else if (current.Filter != null)
{ {
@ -200,6 +219,10 @@ namespace Microsoft.AspNet.Mvc.Core
// Only keep going if we don't have a result // Only keep going if we don't have a result
await InvokeAuthorizationFilterAsync(); await InvokeAuthorizationFilterAsync();
} }
else
{
_logger.LogWarning(AuthorizationFailureLogMessage, current.Filter.GetType().FullName);
}
} }
else else
{ {
@ -254,6 +277,10 @@ namespace Microsoft.AspNet.Mvc.Core
// If we get here then the filter didn't call 'next' indicating a short circuit // If we get here then the filter didn't call 'next' indicating a short circuit
if (_resourceExecutingContext.Result != null) if (_resourceExecutingContext.Result != null)
{ {
_logger.LogVerbose(
ResourceFilterShortCircuitLogMessage,
item.FilterAsync.GetType().FullName);
await _resourceExecutingContext.Result.ExecuteResultAsync(ActionContext); await _resourceExecutingContext.Result.ExecuteResultAsync(ActionContext);
} }
@ -271,6 +298,9 @@ namespace Microsoft.AspNet.Mvc.Core
if (_resourceExecutingContext.Result != null) if (_resourceExecutingContext.Result != null)
{ {
// Short-circuited by setting a result. // Short-circuited by setting a result.
_logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName);
await _resourceExecutingContext.Result.ExecuteResultAsync(ActionContext); await _resourceExecutingContext.Result.ExecuteResultAsync(ActionContext);
_resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
@ -369,6 +399,13 @@ namespace Microsoft.AspNet.Mvc.Core
// Exception filters only run when there's an exception - unsetting it will short-circuit // Exception filters only run when there's an exception - unsetting it will short-circuit
// other exception filters. // other exception filters.
await current.FilterAsync.OnExceptionAsync(_exceptionContext); await current.FilterAsync.OnExceptionAsync(_exceptionContext);
if (_exceptionContext.Exception == null)
{
_logger.LogVerbose(
ExceptionFilterShortCircuitLogMessage,
current.FilterAsync.GetType().FullName);
}
} }
} }
else if (current.Filter != null) else if (current.Filter != null)
@ -383,6 +420,13 @@ namespace Microsoft.AspNet.Mvc.Core
// Exception filters only run when there's an exception - unsetting it will short-circuit // Exception filters only run when there's an exception - unsetting it will short-circuit
// other exception filters. // other exception filters.
current.Filter.OnException(_exceptionContext); current.Filter.OnException(_exceptionContext);
if (_exceptionContext.Exception == null)
{
_logger.LogVerbose(
ExceptionFilterShortCircuitLogMessage,
current.Filter.GetType().FullName);
}
} }
} }
else else
@ -476,6 +520,9 @@ namespace Microsoft.AspNet.Mvc.Core
if (_actionExecutedContext == null) if (_actionExecutedContext == null)
{ {
// If we get here then the filter didn't call 'next' indicating a short circuit // If we get here then the filter didn't call 'next' indicating a short circuit
_logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName);
_actionExecutedContext = new ActionExecutedContext( _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext, _actionExecutingContext,
_filters, _filters,
@ -493,6 +540,9 @@ namespace Microsoft.AspNet.Mvc.Core
if (_actionExecutingContext.Result != null) if (_actionExecutingContext.Result != null)
{ {
// Short-circuited by setting a result. // Short-circuited by setting a result.
_logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.Filter.GetType().FullName);
_actionExecutedContext = new ActionExecutedContext( _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext, _actionExecutingContext,
_filters, _filters,
@ -581,6 +631,9 @@ namespace Microsoft.AspNet.Mvc.Core
if (_resultExecutedContext == null) if (_resultExecutedContext == null)
{ {
// Short-circuited by not calling next // Short-circuited by not calling next
_logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName);
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
@ -593,6 +646,9 @@ namespace Microsoft.AspNet.Mvc.Core
else if (_resultExecutingContext.Cancel == true) else if (_resultExecutingContext.Cancel == true)
{ {
// Short-circuited by setting Cancel == true // Short-circuited by setting Cancel == true
_logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName);
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
@ -610,6 +666,9 @@ namespace Microsoft.AspNet.Mvc.Core
if (_resultExecutingContext.Cancel == true) if (_resultExecutingContext.Cancel == true)
{ {
// Short-circuited by setting Cancel == true // Short-circuited by setting Cancel == true
_logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName);
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,

View File

@ -2018,6 +2018,7 @@ namespace Microsoft.AspNet.Mvc
.Returns(tempData); .Returns(tempData);
httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger<ObjectResult>))) httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger<ObjectResult>)))
.Returns(new Mock<ILogger<ObjectResult>>().Object); .Returns(new Mock<ILogger<ObjectResult>>().Object);
httpResponse.Body = new MemoryStream(); httpResponse.Body = new MemoryStream();
var options = new MvcOptions(); var options = new MvcOptions();
@ -2065,6 +2066,7 @@ namespace Microsoft.AspNet.Mvc
new IValueProviderFactory[0], new IValueProviderFactory[0],
new MockScopedInstance<ActionBindingContext>(), new MockScopedInstance<ActionBindingContext>(),
tempData, tempData,
new NullLoggerFactory(),
maxAllowedErrorsInModelState); maxAllowedErrorsInModelState);
return invoker; return invoker;
@ -2127,6 +2129,7 @@ namespace Microsoft.AspNet.Mvc
new IValueProviderFactory[0], new IValueProviderFactory[0],
new MockScopedInstance<ActionBindingContext>(), new MockScopedInstance<ActionBindingContext>(),
Mock.Of<ITempDataDictionary>(), Mock.Of<ITempDataDictionary>(),
new NullLoggerFactory(),
200); 200);
// Act // Act
@ -2227,6 +2230,7 @@ namespace Microsoft.AspNet.Mvc
IReadOnlyList<IValueProviderFactory> valueProviderFactories, IReadOnlyList<IValueProviderFactory> valueProviderFactories,
IScopedInstance<ActionBindingContext> actionBindingContext, IScopedInstance<ActionBindingContext> actionBindingContext,
ITempDataDictionary tempData, ITempDataDictionary tempData,
ILoggerFactory loggerFactory,
int maxAllowedErrorsInModelState) int maxAllowedErrorsInModelState)
: base( : base(
actionContext, actionContext,
@ -2241,6 +2245,7 @@ namespace Microsoft.AspNet.Mvc
valueProviderFactories, valueProviderFactories,
actionBindingContext, actionBindingContext,
tempData, tempData,
loggerFactory,
maxAllowedErrorsInModelState) maxAllowedErrorsInModelState)
{ {
ControllerFactory = controllerFactory; ControllerFactory = controllerFactory;