環境: Visual Studio 2010 (.NET Framework 4), Windows Server AppFabric
トラッキングのカスタマイズ
- WF 4 のカスタム TrackingParticipant の実装
- WF 4 によるビジュアル トラッキング (監視) の実装
- カスタムのトラッキング ビヘイビア (Behavior) の作成と使用
- Windows Server AppFabric の追跡イベントの使用
こんにちは。
Tech Ed (Japan) の Dublin セッション (T6-402) における未実施のデモのさいごとして、Windows Server AppFabric が収集した監視データ (追跡イベント) を使ったカスタムアプリケーションについて説明します。
セッションで PowerShell を使った管理の話をしましたが、セッションの資料に掲載しておいた一覧 (コマンドレットで提供される管理オブジェクトの一覧) を見ていただくとわかる通り、PowerShell には、追跡イベントの集計、閲覧のためのコマンドは提供されてません。(登録されているサービスの確認などは可能です。)
注記 : セッションのデモでも何度か使用しましたが、以下のコマンドで Dublin の PowerShell コマンド (全部) を確認できます。
import-module applicationserver
get-command -module applicationserver
そこで、IIS の Dublin 用のスナップイン (AppFabric ダッシュボード) が提供しているような追跡イベントの検索 (閲覧) をおこなうには、データベース (SQL Server) のテーブルを直接参照します。例えば、SQL Server の Reporting Services を使ったアプリケーションなどを構築して見栄えの良い監視アプリケーションを構築するなど、実運用に沿ったさまざまな運用 / 監視のアプリケーションが作成できるわけです。
今回はブログで紹介しますので、できあがったきれいなアプリケーションではなく、構造をちゃんと理解していただけるよう、あえて PowerShell でこの追跡イベントを確認してみましょう。(データ構造を理解しておくことが重要です。)
これまで WF を例に説明してきましたので、今回も WF を例に説明しましょう。
データ構造の話だけですので、細かな説明は必要ないでしょう。(詳細は、MSDN のドキュメントなどを参照してください。)
Dublin のデータベースには、システムで独自に活用しているテーブルも多数含まれていますが、最終的な追跡イベントの閲覧に関係するテーブルは、ASEventSourcesTable、ASWcfEventsTable、ASWfEventsTable あたりを抑えておけば問題ありません。(ただし、WF の永続化データについては、別のテーブルに保持されています。)
注記 : 例えば、サービスによって収集されたデータは、いったん ASStagingTable に保存され、SQL Agent (Express の場合は、Server Broker) によって上記のテーブルに配信されます。(さらに、このジョブの実行記録は、ASJobsTable に保存されます。) この他にも、デモでご紹介したカスタムのトラッキングプロファイル (TrackingProfile) で登録したカスタムプロパティ (アクティビティの入出力の変数) を登録するテーブル (ASWfEventPropertiesTable) や、デモで説明した WF の期限付きロックの情報を保持するテーブル、IIS スナップインから実行 (予約) したコマンド (中断、再開など) を登録するテーブルなど、さまざまなシステム用のテーブルが存在します。
例えば、PowerShell を使って以下の通り実行すると、WF の追跡イベントの一覧を出力できます。(インスタンス名、データベース名などは、皆さんの環境にあわせて適宜変更してください。)
Add-PSSnapin "SqlServerProviderSnapin100"Add-PSSnapin "SqlServerCmdletSnapin100"function GetEventTypeName($eventid){ if($eventid -eq 104) { return "ActivityScheduledRecord" } if($eventid -eq 103) { return "ActivityStateRecord" } if($eventid -eq 107) { return "BookmarkResumptionRecord" } if($eventid -eq 111) { return "CustomTrackingRecordError" } if($eventid -eq 108) { return "CustomTrackingRecordInfo" } if($eventid -eq 110) { return "CustomTrackingRecordWarning" } if($eventid -eq 105) { return "FaultPropagationRecord" } if($eventid -eq 102) { return "WorkflowInstanceAbortedRecord" } if($eventid -eq 100) { return "WorkflowInstanceRecord" } if($eventid -eq 112) { return "WorkflowInstanceSuspendedRecord" } if($eventid -eq 113) { return "WorkflowInstanceTerminatedRecord" } if($eventid -eq 101) { return "WorkflowInstanceUnhandledExceptionRecord" } return "UnknownRecord"}$SQL = "select ASEventSourcesTable.Name, " + "ASEventSourcesTable.Site, " + "ASEventSourcesTable.VirtualPath, " + "ASWfEventsTable.TimeCreated, " + "ASWfEventsTable.EventTypeId, " + "ASWfEventsTable.Data1Str as State, " + "ASWfEventsTable.Data2Str as ActivityName " + "FROM ASEventSourcesTable INNER JOIN " + "ASWfEventsTable ON ASEventSourcesTable.Id = ASWfEventsTable.EventSourceId"Invoke-Sqlcmd -Query $SQL -ServerInstance ".sqlexpress" -Database ApplicationServerExtensions | ` format-list Name, Site, VirtualPath, TimeCreated, @{Label="EventType"; Expression={GetEventTypeName($_.EventTypeId)}}, State, ActivityName
<< 実行結果 >>
Name : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : WorkflowInstanceRecordState : StartedActivityName : Sequential ServiceName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : WorkflowInstanceRecordState : IdleActivityName : Sequential ServiceName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : ActivityStateRecordState : ClosedActivityName : StartOrderName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : ActivityStateRecordState : ClosedActivityName : StartOrderReplyName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : WorkflowInstanceRecordState : IdleActivityName : Sequential ServiceName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : ActivityStateRecordState : ClosedActivityName : BuyName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:46EventType : WorkflowInstanceRecordState : IdleActivityName : Sequential ServiceName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:08:56EventType : WorkflowInstanceRecordState : UnloadedActivityName : Sequential ServiceName : Service1Site : Default Web SiteVirtualPath : /DemoWorkflow/Service1.xamlxTimeCreated : 2010/08/26 10:09:17EventType : ActivityStateRecordState : ClosedActivityName : Process1
収集された追跡イベントの基本情報 (共通情報) は ASEventSources テーブルに保存され、WF に関する情報は ASWfEventsTable に保存されていますので、上記の通り、これらを結合 (Join) して結果を出力します。なお、使用されている各カラムの情報については MSDN の各ドキュメントに記述されていますので参考にしてください。
MSDN : データベース イベント マッピング
http://msdn.microsoft.com/ja-jp/library/ff637711.aspx
また、第1 回 でも登場した WorkflowInstanceRecord、ActivityStateRecord などのイベントデータの型情報は、EventTypeId のカラム (列) に int 型で保存されていますので、上記の通り、関数 (GetEventTypeName) を作成して変換をおこなっています。(この変換をおこなってくれるコマンドって、ないですよね。。。 この EventTypeId については、以下に記載されています。)
MSDN : 追跡イベントのリファレンス
http://msdn.microsoft.com/ja-jp/library/ee829493.aspx
第 2 回 で説明したビジュアルトラッキングと組み合わせれば、ワークフローインスタンスが、今、どこまで実行されているかをビジュアルに確認することも可能です。Dublin の監視 (追跡) 仕組みを理解して、さまざまな、応用的なアプリケーションを構築できます。
Categories: Uncategorized
3 replies»