web-dev-qa-db-ja.com

ASP.NETMVCコントローラーアクションを呼び出す時間の測定

MVC 4アプリの一部のユーザーは、散発的な速度低下を経験しています。おそらく、すべてのユーザーが問題が発生するたびにその問題を報告するわけではありません。

私の考えは、各コントローラーアクションに費やされた時間を測定し、規定の時間を超えるアクション呼び出しの詳細をログに記録して、さらなる分析を容易にすることです(サーバー/コードの問題を除外または除外するため)。

各アクションにインストルメンテーションコードを追加することを回避できるように、そのような測定を実行するためにフックする便利な方法はありますか?私は現在このプロジェクトにIOCを使用しておらず、この問題を解決するためだけに導入することを躊躇します。

この種の問題に取り組むためのより良い方法はありますか?

23
Eric J.

グローバルアクションフィルターを作成できますか?このようなもの:

_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
    }
}
_

次に、それを `Application_Start() 'のGlobalFiltersコレクションに追加します。

_GlobalFilters.Filters.Add(new PerformanceTestFilter());
_

テスト対象のコントローラーの詳細は、filterContextパラメーターから取得できます。

[〜#〜] update [〜#〜]

フィルタを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());
_
40
Kevin Aenmey

私は通常、この単純なコードをレイアウトビューの下部に追加します。

<!-- Page generated in @((DateTime.UtcNow - HttpContext.Current.Timestamp.ToUniversalTime()).TotalSeconds.ToString("F4")) s -->

次のような出力。

<!-- Page generated in 0.4399 s -->

これは、HttpContextが作成されたときに測定を開始し( ドキュメント による)、出力に書き込む直前に停止するため、かなり正確であるはずです。

すべてのユースケースで機能するとは限りませんが(子アクションを測定する場合、またはMVCアクション以外の時間を無視する場合など)、ビューに貼り付けるのは簡単です。

より高度な診断のために、私は以前は Glimpse を使用していました。

4
Tom Pažourek

試してください ASP.NET 4.5ページインストルメンテーション

これはページレンダリングを計測します。アプリの時間はコントローラーで費やされる可能性がありますが、ビューレンダリングで費やされる時間はたくさんあります。特に、パーシャルやhtmlヘルパーがたくさんある場合。

1
Mathias F

更新-Install-PackageStopWatchを使用してStopwatchNuGetパッケージをインストールします。 ASP.NET MVCアプリのプロファイルと時刻をAzureまで

私のチュートリアルを参照してください ASP.NET MVC 4で非同期メソッドを使用する グローバルアクションフィルタータイマーがあります。 ELMAHを使用してデータをログに記録できます。私のサンプル私のサンプル http://msdn.Microsoft.com/en-us/library/gg416513(v = vs.98) も同じタイミングフィルターを備えており、よりシンプルですが、かみそり以前のものです。

タイミングを有効にするには、ストップウォッチ属性を探します。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new UseStopwatchAttribute());
    }
}
0
RickAndMSFT