監視とテレメトリ (Azure を使用した Real-World Cloud Apps の構築)

作成者 : Rick AndersonTom Dykstra

修正プロジェクトのダウンロード または 電子書籍のダウンロード

Azure 電子書籍 を使用した Real World Cloud Apps の構築 は、Scott Guthrie によって開発されたプレゼンテーションに基づいています。 クラウド向けの Web アプリの開発を成功させるために役立つ 13 のパターンとプラクティスについて説明します。 電子書籍の詳細については、 最初の章を参照してください。

多くのユーザーは、アプリケーションが停止したときに顧客に知らせるために依存しています。 これは、実際にはどこにもベスト プラクティスではなく、特にクラウドでは推奨されません。 迅速な通知の保証はありません。通知を受け取ると、多くの場合、発生した内容に関する最小限のデータや誤解を招くデータが得られます。 優れたテレメトリとログ システムを使用すると、アプリで何が起こっているかを把握でき、問題が発生した場合はすぐに確認でき、トラブルシューティングに役立つ情報を使用できます。

テレメトリ ソリューションを購入またはレンタルする

注意

この記事は、 Application Insights がリリースされる前に作成されました。 Application Insights は、Azure 上のテレメトリ ソリューションに推奨されるアプローチです。 詳細については、「 ASP.NET Web サイトの Application Insights を設定 する」を参照してください。

クラウド環境の素晴らしい点の 1 つは、購入や勝利への道を借りるのはとても簡単です。 テレメトリの例を示します。 多くの労力を費やすことなく、非常にコスト効率の高い優れたテレメトリ システムを稼働させることができます。 Azure と統合する優れたパートナーが多数あり、一部のパートナーには無料レベルがあります。そのため、基本的なテレメトリを何も得ることができます。 Azure で現在使用できる一部の例を次に示します。

Microsoft System Center には、監視機能も含まれています。

テレメトリ システムを使用する簡単な方法を示す New Relic の設定について簡単に説明します。

Azure 管理ポータルで、サービスにサインアップします。 [ 新規] をクリックし、[ ストア] をクリックします。 [ アドオンの選択 ] ダイアログ ボックスが表示されます。 下にスクロールし、[ New Relic] をクリックします。

アドオンを選択する

右矢印をクリックし、目的のサービス レベルを選択します。 このデモでは、Free レベルを使用します。

アドオンをカスタマイズする

右矢印をクリックし、"購入" を確認すると、New Relic がアドオンとしてポータルに表示されるようになりました。

購入を確認する

管理ポータルでの New Relic アドオン

[ 接続情報] をクリックし、ライセンス キーをコピーします。

接続情報

ポータルで Web アプリの [ 構成 ] タブに移動し、[ パフォーマンス監視][アドオン] に設定し、[ アドオンの選択 ] ドロップダウン リストを New Relic に設定します。 [保存] をクリックします。

[構成] タブの New Relic

Visual Studio で、New Relic NuGet パッケージをアプリにインストールします。

[構成] タブの開発者分析

アプリを Azure にデプロイし、使用を開始します。 New Relic が監視するアクティビティを提供するために、いくつかの Fix It タスクを作成します。

次に、ポータルの [アドオン] タブの [New Relic ] ページ 戻り、[ 管理] をクリックします。 ポータルから New Relic 管理ポータルに送信され、認証にシングル サインオンが使用されるため、資格情報を再度入力する必要はありません。 [概要] ページには、さまざまなパフォーマンス統計が表示されます。 (画像をクリックすると、概要ページのフルサイズが表示されます)。

New Relic の [監視] タブ

表示できる統計情報のほんの一部を次に示します。

  • 異なる時間帯の平均応答時間。

    応答時間

  • 1 日の異なる時間におけるスループット レート (1 分あたりの要求数)。

    スループット

  • さまざまな HTTP 要求の処理に費やされたサーバー CPU 時間。

    Web トランザクション時間

  • アプリケーション コードのさまざまな部分で費やされた CPU 時間:

    トレースの詳細

  • パフォーマンス統計の履歴。

    過去のパフォーマンス

  • BLOB サービスなどの外部サービスへの呼び出しと、サービスの信頼性と応答性に関する統計。

    外部サービス

    外部サービス 2

    外部サービス

  • 米国 Web アプリのトラフィックがどこから来たのか、世界のどこにあるかについての情報。

    [地理的な場所]

レポートとイベントを設定することもできます。 たとえば、エラーが表示され始めるたびに、メールを送信して問題をサポート スタッフに通知することができます。

レポート

New Relic は、テレメトリ システムの一例にすぎません。このすべてを他のサービスからも取得できます。 クラウドの美しさは、コードを記述する必要がなく、最小限またはまったく費用をかけずに、アプリケーションの使用方法と顧客が実際に経験している内容に関する多くの情報を突然得ることができるということです。

分析情報のログ

テレメトリ パッケージは適切な最初の手順ですが、独自のコードをインストルメント化する必要があります。 テレメトリ サービスでは、問題が発生したときに通知され、顧客が何を経験しているかがわかりますが、コードで何が起こっているのかについて多くの分析情報が得られない場合があります。

アプリの実行内容を確認するために、運用サーバーにリモート接続する必要はありません。 1 台のサーバーがある場合は実用的ですが、何百ものサーバーにスケーリングし、リモート接続する必要があるサーバーがわからない場合はどうでしょうか。 ログには、問題を分析してデバッグするために運用サーバーにリモート接続する必要がない十分な情報が提供されている必要があります。 ログを介してのみ問題を分離できるように、十分な情報をログに記録する必要があります。

運用環境にログインする

多くの人が、問題があり、デバッグしたい場合にのみ、運用環境でトレースを有効にします。 これにより、問題を認識してから、問題に関する有用なトラブルシューティング情報が得られるまでの間に、大幅な遅延が発生する可能性があります。 また、取得した情報は、断続的なエラーには役立たない可能性があります。

ストレージが安価なクラウド環境で推奨されるのは、運用環境で常にログオンしたままにしておくことです。 そうすることで、エラーが発生したときに既にログに記録され、時間の経過と共に発生する問題や異なるタイミングで定期的に発生する問題を分析するのに役立つ履歴データがあります。 消去プロセスを自動化して古いログを削除することもできますが、ログを保持するよりも、このようなプロセスを設定する方がコストが高くなる場合があります。

ログ記録の追加費用は、問題が発生したときに必要なすべての情報を既に利用できるようにすることで、トラブルシューティングの時間とお金の量と比較して簡単です。 その後、誰かが彼らが最後の夜8時頃にランダムなエラーを持っていたと言ったが、彼らはエラーを覚えていないとき、あなたはすぐに問題が何だったかを見つけることができます。

1 か月に 4 ドル未満の場合は、50 ギガバイトのログを手元に保持できます。また、1 つのことを念頭に置いておく限り、ログ記録のパフォーマンスへの影響は簡単です。パフォーマンスのボトルネックを回避するには、ログ ライブラリが非同期であることを確認してください。

アクションを必要とするログから通知するログを区別する

ログは INFORM (私はあなたが何かを知って欲しい)またはACT(私はあなたが何かをしてほしい)を意図しています。 アクションを実行する人または自動化されたプロセスを本当に必要とする問題については、ACT ログのみを書き込むよう注意してください。 ACT ログが多すぎるとノイズが発生し、本物の問題を見つけるためにすべてを処理する作業が多すぎます。 また、ACT ログでサポート スタッフにメールを送信するなど、何らかのアクションが自動的にトリガーされる場合は、1 つの問題によって何千ものアクションがトリガーされないようにします。

.NET System.Diagnostics トレースでは、ログにエラー、警告、情報、デバッグ/詳細レベルを割り当てることができます。 ACT ログのエラー レベルを予約し、INFORM ログの下位レベルを使用することで、ACT と INFORM ログを区別できます。

ログ レベル

実行時にログ レベルを構成する

運用環境では常にログ記録を有効にする価値はありますが、もう 1 つのベスト プラクティスは、アプリケーションを再デプロイまたは再起動することなく、ログ記録の詳細レベルを実行時に調整できるログ フレームワークを実装することです。 たとえば、 で System.Diagnostics トレース機能を使用すると、エラー、警告、情報、デバッグ/詳細ログを作成できます。 運用環境では常にエラー、警告、情報のログをログに記録することをお勧めします。また、ケース バイ ケースでトラブルシューティングを行うためにデバッグ/詳細ログを動的に追加できるようにすることをお勧めします。

Azure App Service のWeb Appsには、ファイル システム、テーブル ストレージ、または BLOB ストレージにログを書き込System.Diagnosticsむサポートが組み込まれています。 ストレージの宛先ごとに異なるログ レベルを選択できます。また、アプリケーションを再起動することなく、その場でログ レベルを変更できます。 BLOB ストレージのサポートにより、アプリケーション ログで HDInsight 分析ジョブを簡単に実行できます。これは、HDInsight が Blob Storage を直接操作する方法を認識しているためです。

例外をログに記録する

例外を配置するだけではありません 。ログ コード内の ToString() 。 コンテキスト情報は残ります。 SQL エラーの場合、SQL エラー番号は除外されます。 すべての例外について、コンテキスト情報、例外自体、および内部例外を含めて、トラブルシューティングに必要なすべてのものを提供していることを確認します。 たとえば、コンテキスト情報には、サーバー名、トランザクション識別子、およびユーザー名 (パスワードやシークレットは含まれません) が含まれる場合があります。

各開発者に依存して例外ログを使用して正しいことを行う場合は、一部の開発者は実行しません。 毎回正しい方法で実行されるようにするには、例外処理をロガー インターフェイスに直接作成します。例外オブジェクト自体をロガー クラスに渡し、ロガー クラスで例外データを正しくログに記録します。

サービスへの呼び出しをログに記録する

データベース、REST API、外部サービスのいずれであっても、アプリがサービスを呼び出すたびにログを作成することを強くお勧めします。 成功または失敗の兆候だけでなく、各要求にかかった時間をログに含めます。 クラウド環境では、完全な停止ではなく、低速化に関連する問題が頻繁に発生します。 通常 10 ミリ秒かかるものは、突然 1 秒かかる場合があります。 アプリの速度が遅いと誰かに伝えられると、New Relic や自分が持っているテレメトリ サービスを確認し、そのエクスペリエンスを検証できるようにする必要があります。その後、自分のログを確認して、なぜ遅いのかを詳しく調べることができます。

ILogger インターフェイスを使用する

運用アプリケーションを作成するときに行うことをお勧めするのは、単純な ILogger インターフェイスを作成し、その中にいくつかのメソッドを貼り付ける方法です。 これにより、後でログの実装を簡単に変更でき、すべてのコードを実行する必要はありません。 Fix It アプリ全体で クラスを System.Diagnostics.Trace 使用することもできますが、代わりに ILogger を実装するログ クラスの内部で使用し、アプリ全体で ILogger メソッドを呼び出します。

そうすることで、ログ記録を豊かにしたい場合は、任意のログメカニズムに置き換えることができます System.Diagnostics.Trace 。 たとえば、アプリの成長に合わせて、 NLogエンタープライズ ライブラリ ログ アプリケーション ブロックなどのより包括的なログ パッケージを使用することを決定できます。 (Log4Net はもう 1 つの一般的なログ記録フレームワークですが、非同期ログ記録は行いません)。

NLog などのフレームワークを使用する理由の 1 つは、ログ出力を別々の大量および価値の高いデータ ストアに分割しやすいようにすることです。 これにより、ACT データへの迅速なアクセスを維持しながら、高速クエリを実行する必要がない大量の INFORM データを効率的に格納できます。

セマンティック ログ

より有用な診断情報を生成できるログ記録を行う比較的新しい方法については、「 エンタープライズ ライブラリ セマンティック ログ アプリケーション ブロック (SLAB)」を参照してください。 SLAB では、.NET 4.5 での Event Tracing for Windows (ETW) と EventSource のサポートを使用して、より構造化されたクエリ可能なログを作成できます。 ログに記録するイベントの種類ごとに異なるメソッドを定義すると、書き込む情報をカスタマイズできます。 たとえば、SQL Database エラーをログに記録するには、 メソッドをLogSQLDatabaseError呼び出します。 このような例外の場合は、重要な情報がエラー番号であることがわかっているので、メソッドシグネチャにエラー番号パラメーターを含め、書き込むログ レコードに別のフィールドとしてエラー番号を記録できます。 数値は別のフィールドにあるため、エラー番号をメッセージ文字列に連結する場合よりも、SQL エラー番号に基づくレポートをより簡単かつ確実に取得できます。

Fix It アプリでのログ記録

ILogger インターフェイス

Fix It アプリの ILogger インターフェイスを次に示します。

public interface ILogger
{
    void Information(string message);
    void Information(string fmt, params object[] vars);
    void Information(Exception exception, string fmt, params object[] vars);

    void Warning(string message);
    void Warning(string fmt, params object[] vars);
    void Warning(Exception exception, string fmt, params object[] vars);

    void Error(string message);
    void Error(string fmt, params object[] vars);
    void Error(Exception exception, string fmt, params object[] vars);

    void TraceApi(string componentName, string method, TimeSpan timespan);
    void TraceApi(string componentName, string method, TimeSpan timespan, string properties);
    void TraceApi(string componentName, string method, TimeSpan timespan, string fmt, params object[] vars);
}

これらのメソッドを使用すると、 System.Diagnostics でサポートされているのと同じ 4 つのレベルでログを書き込むことができます。 TraceApi メソッドは、待機時間に関する情報を含む外部サービス呼び出しをログに記録するためのものです。 デバッグ/詳細レベル用の一連のメソッドを追加することもできます。

ILogger インターフェイスのロガー実装

インターフェイスの実装は非常に簡単です。 基本的には、標準の System.Diagnostics メソッドを呼び出すだけです。 次のスニペットは、3 つの Information メソッドと、それぞれ 1 つすべてを示しています。

public class Logger : ILogger
{
    public void Information(string message)
    {
        Trace.TraceInformation(message);
    }

    public void Information(string fmt, params object[] vars)
    {
        Trace.TraceInformation(fmt, vars);
    }

    public void Information(Exception exception, string fmt, params object[] vars)
    {
        var msg = String.Format(fmt, vars);
        Trace.TraceInformation(string.Format(fmt, vars) + ";Exception Details={0}", exception.ToString());
    }

    public void Warning(string message)
    {
        Trace.TraceWarning(message);
    }

    public void Error(string message)
    {
        Trace.TraceError(message);
    }

    public void TraceApi(string componentName, string method, TimeSpan timespan, string properties)
    {
        string message = String.Concat("component:", componentName, ";method:", method, ";timespan:", timespan.ToString(), ";properties:", properties);
        Trace.TraceInformation(message);
    }
}

ILogger メソッドの呼び出し

Fix It アプリのコードが例外をキャッチするたびに、 ILogger メソッドを呼び出して例外の詳細をログに記録します。 また、データベース、BLOB サービス、または REST API の呼び出しを行うたびに、呼び出しの前にストップウォッチを開始し、サービスが戻ったときにストップウォッチを停止し、経過時間と成功または失敗に関する情報をログに記録します。

ログ メッセージにクラス名とメソッド名が含まれていることに注意してください。 ログ メッセージで、アプリケーション コードで書き込んだ部分を確実に識別することをお勧めします。

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

    public async Task<FixItTask> FindTaskByIdAsync(int id)
    {
        FixItTask fixItTask = null;
        Stopwatch timespan = Stopwatch.StartNew();

        try
        {
            fixItTask = await db.FixItTasks.FindAsync(id);
            
            timespan.Stop();
            log.TraceApi("SQL Database", "FixItTaskRepository.FindTaskByIdAsync", timespan.Elapsed, "id={0}", id);
        }
        catch(Exception e)
        {
            log.Error(e, "Error in FixItTaskRepository.FindTaskByIdAsynx(id={0})", id);
        }

        return fixItTask;
    }

そのため、Fix It アプリがSQL Databaseの呼び出しを行うたびに、呼び出し、呼び出したメソッド、正確にかかった時間を確認できます。

ログ内のクエリをSQL Databaseする

[Edit Entity Properties]\(エンティティ プロパティの編集\) と、更新に成功した各プロパティの外観と、所要時間を示すスクリーンショット。

ログを参照すると、データベース呼び出しにかかる時間が可変であることがわかります。 この情報は役に立つ可能性があります。このすべてがアプリによってログに記録されるため、データベース サービスの時間の経過に伴うパフォーマンスの履歴傾向を分析できます。 たとえば、ほとんどの場合、サービスは高速ですが、要求が失敗したり、特定の時刻に応答が遅くなったりする可能性があります。

BLOB サービスに対しても同じことを行うことができます。アプリが新しいファイルをアップロードするたびにログがあり、各ファイルのアップロードにかかった正確な時間を確認できます。

BLOB アップロード ログ

サービスを呼び出すたびに記述する追加のコード行は 2 行に過ぎず、誰かが問題に遭遇したと言うたびに、問題が何であったか、エラーだったのか、それとも実行速度が遅かっただけなのかを正確に把握できます。 エラーが発生した後にサーバーにリモート接続したり、ログ記録を有効にしたりすることなく、問題の原因を特定し、再作成することができます。

Fix It アプリでの依存関係の挿入

上記の例のリポジトリ コンストラクターがロガー インターフェイスの実装を取得する方法を疑問に思うかもしれません。

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

インターフェイスを実装に接続するために、アプリは AutoFac依存関係挿入 (DI) を使用します。 DI を使用すると、コード全体の多くの場所でインターフェイスに基づくオブジェクトを使用でき、インターフェイスのインスタンス化時に使用される実装を 1 か所で指定するだけで済みます。 これにより、実装を簡単に変更できます。たとえば、System.Diagnostics ロガーを NLog ロガーに置き換えることができます。 または、自動テストの場合は、ロガーのモック バージョンを置き換える必要があります。

Fix It アプリケーションでは、すべてのリポジトリとすべてのコントローラーで DI が使用されます。 コントローラー クラスのコンストラクターは、リポジトリがロガー インターフェイスを取得するのと同じ方法で ITaskRepository インターフェイスを取得します。

public class DashboardController : Controller
{
    private IFixItTaskRepository fixItRepository = null;

    public DashboardController(IFixItTaskRepository repository)
    {
        fixItRepository = repository;
    }

このアプリでは、AutoFac DI ライブラリを使用して、これらのコンストラクターに TaskRepository インスタンスと Logger インスタンスを自動的に提供します。

public class DependenciesConfig
{
    public static void RegisterDependencies()
    {
        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterType<Logger>().As<ILogger>().SingleInstance();

        builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
        builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();
        builder.RegisterType<FixItQueueManager>().As<IFixItQueueManager>();

        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

このコードは基本的に、コンストラクターが ILogger インターフェイスを必要とする任意の場所で Logger クラスのインスタンスを渡し、 IFixItTaskRepository インターフェイスが必要な場合は常に FixItTaskRepository クラスのインスタンスを渡します。

AutoFac は、使用できる多くの依存関係挿入フレームワークの 1 つです。 もう 1 つの一般的な 方法は Unity です。これは、Microsoft のパターンとプラクティスによって推奨およびサポートされています。

Azure での組み込みのログ記録のサポート

Azure では、Azure App ServiceのWeb Appsに対して次の種類のログ記録がサポートされています。

  • System.Diagnostics トレース (サイトを再起動せずに、オンとオフを切り替えて、その場でレベルを設定できます)。
  • Windows イベント。
  • IIS ログ (HTTP/FREB)。

Azure では、Cloud Servicesで次の種類のログ記録がサポートされています。

  • System.Diagnostics トレース。
  • パフォーマンス カウンター。
  • Windows イベント。
  • IIS ログ (HTTP/FREB)。
  • カスタム ディレクトリの監視。

Fix It アプリでは、System.Diagnostics トレースが使用されます。 Web アプリで System.Diagnostics ログを有効にするために必要なのは、ポータルでスイッチを反転するか、REST API を呼び出す必要があります。 ポータルで、サイトの [ 構成 ] タブをクリックし、下にスクロールして [ アプリケーション診断 ] セクションを表示します。 ログ記録のオンとオフを切り替えて、目的のログ レベルを選択できます。 Azure でファイル システムまたはストレージ アカウントにログを書き込むことができます。

[構成] タブのアプリ 診断とサイト 診断

Azure でログ記録を有効にすると、作成されたログが Visual Studio の [出力] ウィンドウに表示されます。

[ストリーミング ログ] メニュー

[ストリーミング ログ] メニュー 2

また、ログをストレージ アカウントに書き込み、Visual Studio のサーバー エクスプローラーや Azure Storage Explorer など、Azure Storage Table Service にアクセスできる任意のツールでログ表示することもできます。

サーバー エクスプローラーのログ

まとめ

すぐに使用できるテレメトリ システムを実装し、独自のコードでログ記録をインストルメント化し、Azure でログ記録を構成するのは非常に簡単です。 また、運用環境の問題がある場合は、テレメトリ システムとカスタム ログを組み合わせることで、問題が顧客の大きな問題になる前に迅速に解決できます。

次の では、一時的なエラーを処理して、調査する必要がある運用環境の問題にならないようにする方法について説明します。

リソース

詳細については、次のリソースを参照してください。

主にテレメトリに関するドキュメント:

主にログ記録に関するドキュメント:

主にトラブルシューティングに関するドキュメント:

ビデオ:

  • FailSafe: スケーラブルで回復性の高いCloud Servicesの構築。 ウルリッヒ・ホーマン、マルク・メルキュール、マーク・シムズによる9部構成のシリーズ。 Microsoft カスタマー アドバイザリ チーム (CAT) の経験から実際の顧客に関するストーリーを含む、非常にアクセスしやすい興味深い方法で、高レベルの概念とアーキテクチャの原則を提示します。 エピソード 4 と 9 は、監視とテレメトリに関するページです。 エピソード 9 には、監視サービス MetricsHub、AppDynamics、New Relic、PagerDuty の概要が含まれています。
  • 大きなビルド: Azure のお客様から学んだ教訓 - パート 2. Mark Simms は、障害の設計とすべてをインストルメント化することについて話します。 Failsafe シリーズと似ていますが、詳細な操作方法について説明します。

コード サンプル: