Add logging of elapsed time for the action.

This commit is contained in:
Ryan Nowak 2015-10-22 16:26:48 -07:00
parent cea8d019f1
commit ec2abc8ae0
3 changed files with 49 additions and 8 deletions

View File

@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure
var actionDescriptor = await _actionSelector.SelectAsync(context);
if (actionDescriptor == null)
{
_logger.LogVerbose("No actions matched the current request.");
_logger.NoActionsMatched();
return;
}
@ -90,10 +90,13 @@ namespace Microsoft.AspNet.Mvc.Infrastructure
using (_logger.ActionScope(actionDescriptor))
{
_logger.LogVerbose("Executing action {ActionDisplayName}", actionDescriptor.DisplayName);
_logger.ExecutingAction(actionDescriptor);
var startTime = Environment.TickCount;
await InvokeActionAsync(context, actionDescriptor);
context.IsHandled = true;
_logger.ExecutedAction(actionDescriptor, startTime);
}
}
finally

View File

@ -10,11 +10,43 @@ namespace Microsoft.AspNet.Mvc.Logging
{
internal static class MvcRouteHandlerLoggerExtensions
{
private static Action<ILogger, string, Exception> _actionExecuting;
private static Action<ILogger, string, double, Exception> _actionExecuted;
static MvcRouteHandlerLoggerExtensions()
{
_actionExecuting = LoggerMessage.Define<string>(
LogLevel.Verbose,
1,
"Executing action {ActionName}");
_actionExecuted = LoggerMessage.Define<string, double>(
LogLevel.Information,
2,
"Executed action {ActionName} in {ElapsedMilliseconds}ms");
}
public static IDisposable ActionScope(this ILogger logger, ActionDescriptor action)
{
return logger.BeginScopeImpl(new ActionLogScope(action));
}
public static void ExecutingAction(this ILogger logger, ActionDescriptor action)
{
_actionExecuting(logger, action.DisplayName, null);
}
public static void ExecutedAction(this ILogger logger, ActionDescriptor action, int startTicks)
{
var elapsed = new TimeSpan(Environment.TickCount - startTicks);
_actionExecuted(logger, action.DisplayName, elapsed.TotalMilliseconds, null);
}
public static void NoActionsMatched(this ILogger logger)
{
logger.LogVerbose(3, "No actions matched the current request");
}
private class ActionLogScope : ILogValues
{
private readonly ActionDescriptor _action;

View File

@ -25,13 +25,16 @@ namespace Microsoft.AspNet.Mvc.Infrastructure
// Arrange
var sink = new TestSink();
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
var displayName = "A.B.C";
var actionDescriptor = new Mock<ActionDescriptor>();
actionDescriptor.SetupGet(ad => ad.DisplayName)
.Returns(displayName);
actionDescriptor
.SetupGet(ad => ad.DisplayName)
.Returns(displayName);
var context = CreateRouteContext(actionDescriptor: actionDescriptor.Object, loggerFactory: loggerFactory);
var handler = new MvcRouteHandler();
var expectedMessage = $"Executing action {displayName}";
// Act
await handler.RouteAsync(context);
@ -39,8 +42,11 @@ namespace Microsoft.AspNet.Mvc.Infrastructure
// Assert
Assert.Single(sink.Scopes);
Assert.Equal(displayName, sink.Scopes[0].Scope?.ToString());
Assert.Single(sink.Writes);
Assert.Equal(expectedMessage, sink.Writes[0].State?.ToString());
Assert.Equal(2, sink.Writes.Count);
Assert.Equal($"Executing action {displayName}", sink.Writes[0].State?.ToString());
// This message has the execution time embedded, which we don't want to verify.
Assert.StartsWith($"Executed action {displayName} ", sink.Writes[1].State?.ToString());
}
[Fact]
@ -59,7 +65,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure
loggerFactory: loggerFactory);
var handler = new MvcRouteHandler();
var expectedMessage = "No actions matched the current request.";
var expectedMessage = "No actions matched the current request";
// Act
await handler.RouteAsync(context);