发出用户代码跟踪

除了在配置中启用跟踪以收集 Windows Communication Foundation (WCF)生成的检测数据外,还可以以编程方式在用户代码中发出跟踪。 这样,便可以主动创建检测数据,以便稍后进行诊断。 本主题讨论如何完成这项任务。

此外, 扩展跟踪 示例包括以下部分演示的所有代码。

创建跟踪源

可以使用以下代码创建用户跟踪源。

TraceSource ts = new TraceSource("myUserTraceSource");

创建活动

活动是逻辑处理的单元。 对于您希望在其中组合跟踪的每个主要处理单元,可为其创建一个活动。 例如,可以为服务的每个请求创建一个活动。 为此,请执行以下步骤。

  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跟踪源的属性设置为trueSystem.ServiceModel,则在添加请求时,服务处理过程将在客户端中定义的同一活动内进行。 如果服务定义了自己的活动和传输,则服务跟踪不会显示在客户端传播的活动中。 相反,它们通过将跟踪转移到其 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)查看时运行扩展跟踪示例生成的跟踪的屏幕截图。

在下图中,在左侧面板中选择了之前创建的“添加请求”活动。 它与其他三个数学运算活动(除、减、乘)一起列出,这些活动构成应用程序客户端应用程序。 用户代码为每个作定义了一个新活动,以隔离不同请求中可能出现的错误事件。

为了演示如何在扩展跟踪示例中使用传输功能,还创建了一个封装四个操作请求的计算器活动。 对于每个请求,它们都将在“Calculator activity”(计算器活动)与请求活动之间来回转移(跟踪在图中的面板右上方突出显示)。

在左侧面板中选择活动时,此活动包含的跟踪将显示在右上角面板上。 如果请求路径的每个终结点上的 propagateActivity 均为 true,请求活动中的跟踪将来自参与请求的所有进程。 在此示例中,您可以在面板的第4列中看到来自客户端和服务端的跟踪。

此活动显示以下处理顺序:

  1. 客户端将消息发送到“Add”。

  2. 服务接收“添加请求”消息。

  3. 服务发送“Add”响应。

  4. 客户端接收“Add”响应。

所有这些跟踪均在“信息”级别发出。 单击面板右上方的跟踪将在面板右下方显示此跟踪的详细信息。

在下图中,我们还看到跟踪在“Calculator activity”(计算器活动)中来回转移,而且每个请求活动都具有两对“开始”和“停止”跟踪,一对用于客户端,另一对用于服务(每个跟踪源一对)。

跟踪查看器:生成用户代码跟踪 列出按创建时间排序的活动(左侧面板)及其包含的嵌套活动(右上角面板)

如果服务代码引发导致客户端也引发的异常(例如,当客户端未收到响应其请求时),则服务与客户端警告或错误消息都在同一活动中发生,以便直接关联。 在下图中,该服务将引发一个异常,指出“服务拒绝在用户代码中处理此请求”。客户端还会引发一个异常,指出“服务器由于内部错误而无法处理请求”。

下图显示,如果传播了请求活动 ID,给定请求的各终结点上的错误将显示在同一个活动中:

屏幕截图显示特定请求在各终结点出现的错误。

双击左侧面板中的“乘法操作”会显示以下图表,其中展示了涉及的每个进程的乘法操作的跟踪。 我们可以看到,服务端首先出现了一个警告(引发异常),随后由于无法处理请求,客户端上出现了警告和错误。 因此,我们可以暗示终结点之间的因果错误关系,并派生错误的根本原因。

下图显示了错误相关性的图形视图:

显示错误相关性图形视图的屏幕截图。

为了获取以前的跟踪,我们为用户跟踪源设置ActivityTracing,并为propagateActivity=true跟踪源设置System.ServiceModel。 我们没有为 ActivityTracing 跟踪源设置 System.ServiceModel,以便实现用户代码活动之间的传播。 (当启用“ServiceModel”活动跟踪时,客户端中定义的活动 ID 将不会传播到服务用户代码;但是,转移会将客户端和服务用户代码活动与中间的 WCF 活动相关联。)

定义活动和传播活动 ID 使我们能够跨终结点执行直接错误关联。 通过这种方式,我们可以更快地找到错误的根本原因。

另请参阅