Измерение времени вызова действий контроллера ASP.NET MVC
Некоторые пользователи приложения MVC 4 испытывают спорадическую медлительность. Предположительно, не каждый пользователь сообщает об этой проблеме каждый раз, когда это происходит с ним.
Моя мысль состоит в том, чтобы измерить время, затрачиваемое на каждое действие контроллера, и зарегистрировать детали вызовов действий, которые превышают предписанное время, чтобы облегчить дальнейший анализ (чтобы исключить или исключить проблему с сервером / кодом).
Есть ли удобный способ подключиться к выполнению таких измерений, чтобы избежать добавления инструментария к каждому действию? В настоящее время я не использую МОК для этого проекта и не хотел бы представлять его только для решения этой проблемы.
Есть ли лучший способ решения этой проблемы?
4 ответа
Не могли бы вы создать глобальный фильтр действий? Что-то вроде этого:
public class PerformanceTestFilter : IActionFilter
{
private Stopwatch stopWatch = new Stopwatch();
public void OnActionExecuting(ActionExecutingContext filterContext)
{
stopWatch.Reset();
stopWatch.Start();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
stopWatch.Stop();
var executionTime = stopWatch.ElapsedMilliseconds;
// Do something with the executionTime
}
}
а затем добавить его в свой GlobalFilters
коллекция в `Application_Start()'
GlobalFilters.Filters.Add(new PerformanceTestFilter());
Вы можете получить подробную информацию о тестируемом контроллере от filterContext
параметр.
ОБНОВИТЬ
Добавление фильтра в GlobalFilters
коллекция напрямую создаст единый экземпляр фильтра для всех действий. Это, конечно, не будет работать для синхронизации одновременных запросов. Чтобы создать новый экземпляр для каждого действия, создайте поставщика фильтров:
public class PerformanceTestFilterProvider : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
return new[] {new Filter(new PerformanceTestFilter(), FilterScope.Global, 0)};
}
}
Затем вместо непосредственного добавления фильтра добавьте поставщика фильтров в Application_Start()
:
FilterProviders.Providers.Add(new PerformanceTestFilterProvider());
Я обычно добавляю этот простой код в конец моего представления Layout:
<!-- Page generated in @((DateTime.UtcNow - HttpContext.Current.Timestamp.ToUniversalTime()).TotalSeconds.ToString("F4")) s -->
Выводит что-то вроде:
<!-- Page generated in 0.4399 s -->
Это начинает измерять, когда HttpContext
создается (в соответствии с документацией) и останавливается непосредственно перед записью в вывод, поэтому он должен быть довольно точным.
Он может не работать для всех случаев использования (если вы хотите измерить дочерние действия или игнорировать время вне действия MVC и т. Д.), Но его легко вставить в представление.
Для более продвинутой диагностики я использовал Glimpse.
Попробуйте ASP.NET 4.5 Page Инструментарий
Это инструменты рендеринга страницы: время вашего приложения может быть потрачено в контроллере, но есть много раз, когда оно тратится на визуализацию. Особенно, если у вас есть много частичных и HTML-помощников.
Обновление - установите мой пакет секундомера NuGet с помощью Install-Package StopWatch, см. Профиль и время вашего приложения ASP.NET MVC вплоть до Azure.
См. Мое руководство Использование асинхронных методов в ASP.NET MVC 4, в котором есть глобальный таймер фильтра действий. Вы можете использовать ELMAH для регистрации данных. Мой образец Мой образец http://msdn.microsoft.com/en-us/library/gg416513(v=vs.98) также имеет тот же фильтр синхронизации и является более простым, но это pre-Razor.
Ищите атрибут секундомера, чтобы включить синхронизацию.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new UseStopwatchAttribute());
}
}