次の方法で共有


ユーザー コード トレースの出力

構成でトレースを有効にして、Windows Communication Foundation (WCF) によって生成されたインストルメンテーション データを収集するだけでなく、ユーザー コードでプログラムによってトレースを出力することもできます。 この方法では、後で診断目的で熟読できるインストルメンテーション データを事前に作成できます。 このトピックでは、これを行う方法について説明します。

さらに、 拡張トレース のサンプルには、次のセクションで示すすべてのコードが含まれています。

トレース ソースの作成

次のコードを使用して、ユーザー トレース ソースを作成できます。

TraceSource ts = new TraceSource("myUserTraceSource");

アクティビティの作成

アクティビティは、処理の論理単位です。 トレースをグループ化する主要な処理単位ごとに 1 つのアクティビティを作成できます。 たとえば、サービスへの要求ごとに 1 つのアクティビティを作成できます。 これを行うには、次の手順を実行します。

  1. アクティビティ ID をスコープに保存します。

  2. 新しいアクティビティ ID を作成します。

  3. スコープ内のアクティビティから新しいアクティビティに転送し、スコープに新しいアクティビティを設定し、そのアクティビティの開始トレースを出力します。

次のコードは、これを行う方法を示しています。

Guid oldID = Trace.CorrelationManager.ActivityId;
Guid traceID = Guid.NewGuid();
ts.TraceTransfer(0, "transfer", traceID);
Trace.CorrelationManager.ActivityId = traceID; // Trace is static
ts.TraceEvent(TraceEventType.Start, 0, "Add request");

ユーザー アクティビティ内でのトレースの出力

次のコードは、ユーザー アクティビティ内でトレースを出力します。

double value1 = 100.00D;
double value2 = 15.99D;
ts.TraceInformation("Client sends message to Add " + value1 + ", " + value2);
double result = client.Add(value1, value2);
ts.TraceInformation("Client receives Add response '" + result + "'");

アクティビティの停止

アクティビティを停止するには、古いアクティビティに戻り、現在のアクティビティ ID を停止し、スコープ内の古いアクティビティ ID をリセットします。

次のコードは、これを行う方法を示しています。

ts.TraceTransfer(0, "transfer", oldID);
ts.TraceEvent(TraceEventType.Stop, 0, "Add request");
Trace.CorrelationManager.ActivityId = oldID;

アクティビティ ID をサービスに伝達する

propagateActivity属性をクライアント構成ファイルとサービス構成ファイルの両方でtrueトレース ソースのSystem.ServiceModelに設定した場合、Add 要求のサービス処理は、クライアントで定義されたものと同じアクティビティで行われます。 サービスが独自のアクティビティと転送を定義している場合、サービス トレースはクライアント伝達アクティビティには表示されません。 その代わり、クライアントから ID が伝達されたアクティビティに、転送トレースにより、関連付けられたアクティビティにサービス トレースが表示されます。

propagateActivity属性がクライアントとサービスの両方でtrueに設定されている場合、サービスの操作スコープ内のアンビエント アクティビティは WCF によって設定されます。

次のコードを使用して、WCF によってスコープ内でアクティビティが設定されたかどうかを確認できます。

// Check if an activity was set in scope by WCF, if it was
// propagated from the client. If not, ( ambient activity is
// equal to Guid.Empty), create a new one.
if(Trace.CorrelationManager.ActivityId == Guid.Empty)
{
    Guid newGuid = Guid.NewGuid();
    Trace.CorrelationManager.ActivityId = newGuid;
}
// Emit your Start trace.
ts.TraceEvent(TraceEventType.Start, 0, "Add Activity");

// Emit the processing traces for that request.
serviceTs.TraceInformation("Service receives Add "
                            + n1 + ", " + n2);
// double result = n1 + n2;
serviceTs.TraceInformation("Service sends Add result" + result);

// Emit the Stop trace and exit the method scope.
ts.TraceEvent(TraceEventType.Stop, 0, "Add Activity");
// return result;

コード内でスローされる例外のトレース

コードで例外をスローする場合は、次のコードを使用して、警告レベルまたは上のレベルで例外をトレースすることもできます。

ts.TraceEvent(TraceEventType.Warning, 0, "Throwing exception " + "exceptionMessage");

サービス トレース ビューアー ツールでのユーザー トレースの表示

このセクションには、サービス トレース ビューアー ツール (SvcTraceViewer.exe) を使用して表示した場合に、拡張トレース サンプルを実行して生成されたトレースのスクリーンショットが含まれています。

次の図では、前に作成した "要求の追加" アクティビティが左側のパネルで選択されています。 これは、アプリケーション クライアント プログラムを構成する他の 3 つの算術演算アクティビティ (除算、減算、乗算) と共に一覧表示されます。 ユーザー コードは、異なる要求で発生する可能性のあるエラーを分離するために、操作ごとに 1 つの新しいアクティビティを定義しました。

拡張トレース サンプルでの転送の使用方法を示すために、4 つの操作要求をカプセル化する Calculator アクティビティも作成されます。 要求ごとに、Calculator アクティビティから要求アクティビティへの転送が行き来します (図の右上のパネルでトレースが強調表示されています)。

左側のパネルでアクティビティを選択すると、このアクティビティに含まれるトレースが右上のパネルに表示されます。 propagateActivityが要求パス内のすべてのエンドポイントでtrueされている場合、要求アクティビティ内のトレースは、要求に参加するすべてのプロセスから取得されます。 この例では、パネルの 4 番目の列にクライアントとサービスの両方からのトレースを表示できます。

このアクティビティは、次の処理順序を示します。

  1. クライアントがメッセージを Add に送信します。

  2. サービスは Add 要求メッセージを受信します。

  3. サービスが追加の応答を送信します。

  4. クライアントは追加応答を受け取ります。

これらすべてのトレースは、Information レベルで出力されています。 右上のパネルでトレースをクリックすると、そのトレースの詳細が右下のパネルに表示されます。

次の図では、Calculator アクティビティとの間の転送トレースと、要求アクティビティごとに 2 組の Start トレースと Stop トレース (1 つはクライアント用、1 つはサービス用 (トレース ソースごとに 1 つ) も表示されます。

トレース ビューアー: ユーザー コード トレースの出力 作成時間別のアクティビティの一覧 (左パネル) とその入れ子になったアクティビティ (右上のパネル)

サービスコードが例外をスローし、それが原因でクライアントも例外をスローする場合(たとえば、クライアントがその要求への応答を受け取らなかった場合)、サービスとクライアントの警告メッセージまたはエラーメッセージは、直接関連付けるために同じアクティビティで発生します。 次の図では、"サービスはユーザー コードでこの要求の処理を拒否しています" という例外がサービスによってスローされます。クライアントは、"サーバーが内部エラーのために要求を処理できませんでした" という例外もスローします。

次の図は、要求アクティビティ ID が伝達された場合、特定の要求のエンドポイント間のエラーが同じアクティビティに表示されることを示しています。

特定の要求のエンドポイント間のエラーを示すスクリーンショット。

左側のパネルで乗算アクティビティをダブルクリックすると、次のグラフが表示され、関係する各プロセスの乗算アクティビティのトレースが表示されます。 まずサービスで発生した警告 (スローされた例外) が表示され、それに続いて、要求を処理できなかったために発生したクライアントの警告とエラーが表示されます。 したがって、エンドポイント間の因果関係を暗示し、エラーの根本原因を導き出すことができます。

次の図は、エラーの相関関係のグラフ ビューを示しています。

エラーの相関関係のグラフ ビューを示すスクリーンショット。

前のトレースを取得するには、ユーザー トレース ソースのActivityTracingと、propagateActivity=true トレース ソースのSystem.ServiceModelを設定します。 ユーザー コード間のアクティビティの伝達を有効にするために、ActivityTracingSystem.ServiceModelトレース ソースに設定しませんでした。 (ServiceModelのアクティビティトレースがオンの場合、クライアントで定義されたアクティビティIDはサービスユーザーコードまで完全には伝播しません。ただし、クライアントとサービスユーザーコードのアクティビティは、中間のWCFアクティビティと関連付けられます。)

アクティビティを定義し、アクティビティ ID を伝達することで、エンドポイント間で直接エラーの相関関係を実行できます。 これにより、エラーの根本原因をより迅速に特定できます。

こちらも参照ください