原文の記事の投稿日: 2011 年 8 月 24 日 (水曜日)

Windows Azure 診断の使用方法を説明する投稿や記事が多数存在します。ところが、最新機能の詳細を具体的に示そうとすると、さまざまな情報が溢れていて逆に困ります。多種多様な記事が存在しますが、そこで扱われる Azure のリリースは多岐にわたるため、最新の Azure SDK (1.4) の操作について理解しようとすると、多くの時間を費やすことになります。そうした中、この投稿では、Azure 診断を SDK バージョン 1.4 で使用する場合に絞って、その要点について説明します。

 

まず、だれもが知っていることでしょうが、Azure にはトレース リスナーが組み込まれています。このトレース リスナーは、Trace.* コマンド (Trace.Write、Trace.WriteLine、Trace.TraceInformation など) を取得してメモリに格納します。ただし、これらのコマンドをメモリから永続記憶装置に移動するには "なんらかの操作" が必要で、たとえば、データの手動転送を開始したり、転送の実行スケジュールを構成したりする必要があります。また、そうした操作以外にも、イベント ログから情報を移動したり、パフォーマンス カウンターをキャプチャしたり、IIS ログやカスタム ログを移動したりする操作を選択することもできます。

 

前述の一般的なログ記録および診断ツールに加えて、アプリケーションをホストする Azure サーバーへの RDP を許可したり、IntelliTrace を有効にして展開済みアプリケーションでデバッグおよびトラブルシューティングを制限付きで実行したりするように展開を構成することもできます。それでは、そうしたさまざまな構成について詳しく説明します。

 

データを記憶域に永続化する頻度、割り当てる必要がある記憶域の容量、キャプチャするパフォーマンス カウンターなど、各種診断コンポーネントを構成するには、標準 Web ロール Azure アプリケーションに付属する WebRole.cs ファイルにいくつかのコードを記述するのが最も簡単です (また、VM ロール以外のほとんどの Azure 機能には、ワーカー ロール プロジェクトに関する WorkerRole.cs ファイルなどの WebRole クラスとの類似点があると思います)。コードの説明を始める前に、使用する Azure ロール プロジェクトで [構成] (Configuration) タブの [診断結果のストレージ アカウントの資格情報を指定します] (Specify the storage account credentials for the Diagnostics results) チェック ボックスをオンにしてください。そこで選択ボタンを使用して、Azure のストレージ アカウントを選択します。ローカル展開を使用しないでください。この操作によって、Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString という名前のプロジェクトへの新しい接続文字列が保存されます。

 

それでは、まず、Web ロール クラスのコード全体について説明し、その後、いくつかの部分について詳しく説明します。

 

public override bool OnStart()

{

   // For information on handling configuration changes

   // see the MSDN topic at http://go.microsoft.com/fwlink/?linkid=166357&clcid=0x411 (英語)

 

   try

   {

       //initialize the settings framework

                Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>

       {

          configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

       });

 

       //get the storage account using the default Diag connection string

       CloudStorageAccount cs =

          CloudStorageAccount.FromConfigurationSetting(

          "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString");

 

       //get the diag manager

       RoleInstanceDiagnosticManager dm = cs.CreateRoleInstanceDiagnosticManager(

          RoleEnvironment.DeploymentId,

          RoleEnvironment.CurrentRoleInstance.Role.Name,

          RoleEnvironment.CurrentRoleInstance.Id);

 

       //get the current configuration

       DiagnosticMonitorConfiguration dc = dm.GetCurrentConfiguration();

 

       //if that failed, get the values from config file

       if (dc == null)

          dc = DiagnosticMonitor.GetDefaultInitialConfiguration();

 

       //Windows Azure Logs

       dc.Logs.BufferQuotaInMB = 10;

       dc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

       dc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

 

       //Windows Event Logs

       dc.WindowsEventLog.BufferQuotaInMB = 10;

       dc.WindowsEventLog.DataSources.Add("System!*");

       dc.WindowsEventLog.DataSources.Add("Application!*");

       dc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(15);

 

       //Performance Counters

       dc.PerformanceCounters.BufferQuotaInMB = 10;

       PerformanceCounterConfiguration perfConfig =

          new PerformanceCounterConfiguration();

       perfConfig.CounterSpecifier = @"\Processor(_Total)\% Processor Time";

       perfConfig.SampleRate = System.TimeSpan.FromSeconds(60);

      dc.PerformanceCounters.DataSources.Add(perfConfig);

       dc.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(10);

 

       //Failed Request Logs

       dc.Directories.BufferQuotaInMB = 10;

       dc.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(30);

 

       //Infrastructure Logs

       dc.DiagnosticInfrastructureLogs.BufferQuotaInMB = 10;

       dc.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter =

          LogLevel.Verbose;

       dc.DiagnosticInfrastructureLogs.ScheduledTransferPeriod =

          TimeSpan.FromMinutes(60);

 

       //Crash Dumps

       CrashDumps.EnableCollection(true);

 

       //overall quota; must be larger than the sum of all items

       dc.OverallQuotaInMB = 5000;

 

       //save the configuration

       dm.SetCurrentConfiguration(dc);

   }

   catch (Exception ex)

   {

       System.Diagnostics.Trace.Write(ex.Message);

   }

 

   return base.OnStart();

}

 

このコードについて少し詳しく説明します。まず、診断に使用する接続文字列の値を取得して、使用するストレージ アカウントに接続できるようにします。次に、このストレージ アカウントを使用して、診断監視構成クラスを操作します。これが整うと、各種ログ コンポーネントの構成を開始できます。

 

Windows Azure ログには Trace.* の呼び出しがすべて保存されます。ここでは、Windows Azure ログで使用するテーブルに最大 10 MB のデータを格納するように構成し、ログ レベルが詳細の書き込みすべてを対象に、テーブルへの書き込みを 5 分間隔で実行するように構成します。ちなみに、このログ データを格納するために Windows Azure で使用する各種テーブルとキューの一覧については、 http://msdn.microsoft.com/ja-jp/library/hh180875.aspx および http://msdn.microsoft.com/ja-jp/library/microsoft.windowsazure.diagnostics.diagnosticmonitorconfiguration.aspx を参照してください。インフラストラクチャ ログと診断ログは仮想的には同一です。

 

イベント ビューアーの項目については、キャプチャする各ログを WindowsEventLog クラスの DataSources のリストに追加する必要があります。私が追加したのは、Application!*、System!*、または UserData!* です。これ以外のプロパティは Windows Azure ログと同じです。

 

パフォーマンス カウンターについては、キャプチャするカウンターとデータをサンプル抽出する頻度を定義する必要があります。上記の例では、CPU のカウンターを追加して、60 秒間隔でデータをサンプル抽出するように構成しています。

 

最後に、いくつかの処理について説明します。クラッシュ ダンプのキャプチャを有効にし、すべてのログ データのクォータの総量を約 5 GB に変更した後、変更内容を保存します。クォータの総量を増やすことは非常に重要です。クォータの総量を増やしておかないと、記憶域の容量不足で上記の変更を実行できないことを知らせる例外がスローされる可能性があります。これまでの経験上、5 GB なら安全と思われますが、どの値が適切であるかは状況によって異なることがあります。

 

準備ができたので、次は、アプリケーションを発行します。アプリケーションを Visual Studio から発行するときは、次のいくつかの点に注意します。

 

 

[Windows Azure 発行設定] (Window Azure Publish Settings) ダイアログで、[.NET 4 のロールに対して IntelliTrace を有効にします] (Enable IntelliTrace for .NET 4 roles) チェック ボックスをオンにする必要があります。これについては後で詳しく説明します。また、[リモート デスクトップ接続の構成] (Configure Remote Desktop connections) リンクをクリックすることもお勧めします。場合によっては、これ以外に問題を解決する方法がないことがあります。リモート デスクトップに関するドキュメントは最新のものが少なくなって来ているため、構成を手動で変更するよりも、このダイアログを使用することをお勧めします。このリンクをクリックすると、次のようなダイアログが表示されます。

 

 

主な注意事項は次のとおりです。

  1. 所有している PFX ファイルに対してはどの証明書でも使用できるようです。アプリケーションを発行する前に、この証明書をホスト対象サービスに必ずアップロードしてください。
  2. [ユーザー名] (User name) フィールドには任意の値を設定できます。設定したユーザー名とパスワードを使用してローカル アカウントが作成されます。

 

これで、両方のダイアログで必要な操作を完了して、アプリケーションを発行できました。アプリケーションを一度検索して起動し、Web ロールのコードが実行されることを確認します。確認が終了したら、アプリケーションの診断設定を調べて、ここに示す実装済みのカスタマイズを表示できる必要があります (メモ: Azure の管理には無償の CodePlex ツールを使用しています。このツールは http://wapmmc.codeplex.com/ (英語) からダウンロードできます)。

 

 

いくつかのコードを実行し、Windows Azure ログの次のスケジュール済み転送期間 (Scheduled Transfer Period) になるまで待機したら、次のように、Trace.* の呼び出しを WADLogsTable で確認できます。

 

 

また、RDP のサポートをアプリケーションに構成しているため、Web ロールをクリックすると、アプリケーションへの RDP 接続を作成するオプションが Azure Developer Portal のツールバーで有効になります。

 

 

これで、アプリケーションのログとトレースがすべて揃います。さらに調査が必要な場合は、サーバーへの RDP を実行できます。私が有効にしたお勧め機能にはもう 1 つ、IntelliSense があります。IntelliSense については、この投稿で扱う範囲を越えていますが、 http://blogs.msdn.com/b/jnak/archive/2010/06/07/using-intellitrace-to-debug-windows-azure-cloud-services.aspx (英語)http://blogs.msdn.com/b/ianhu/archive/2010/03/16/intellitrace-what-we-collect.aspx (英語) に非常に有益な情報が記載されています。IntelliTrace を有効にしていると、ホスト対象サービスを Visual Studio サーバー エクスプローラーに表示したときに、IntelliTrace が有効になっていることが表示されます。

 

 

次に、アプリケーションのインスタンスを右クリックして、[IntelliTrace ログの表示] (View IntelliTrace logs) メニュー項目を選択できます。このメニュー項目を選択すると、IntelliTrace ログを Azure からダウンロードして Visual Studio で開くことができます。次に例を示します

 

 

この図からわかるように、使用されたスレッド、発生した例外、システム情報、読み込まれたモジュールなどを確認できます。このことを実際に確認するために、診断情報を格納する記憶域の総量を 5 MB に設定して例外をシミュレートしました。変更を加えてアプリケーションを発行し、2 ~ 3 分後に IntelliTrace ログをダウンロードしてみると、思ったとおり、ログの 2 ページ目にエラーが見つかりました。その様子を次に示します。

 

 

これでおわかりでしょう。以上が Windows Azure 1.4 の診断の概要です。Trace イベント、パフォーマンス カウンター、IIS ログ、クラッシュ ダンプ、およびカスタム診断ログ ファイルをキャプチャしています。必要に応じて追加のトラブルシューティングを行う場合は、サーバーへの RDP を実行できます。IntelliTrace ログをアプリケーションからダウンロードして、Visual Studio 2010 のローカル インスタンスでデバッグを制限付きで実行できます。

これはローカライズされたブログ投稿です。原文の記事は、「Windows Azure 1.4 Diagnostics All Up Overview」をご覧ください。