跟踪配置文件包含跟踪查询,这些查询允许跟踪参与者订阅当工作流实例的状态在运行时发生更改时发出的工作流事件。
跟踪配置文件
跟踪概况用于指定要为工作流实例发送哪些跟踪信息。 如果未指定配置文件,则发出所有跟踪事件。 如果指定了配置文件,将发出在配置文件中指定的跟踪事件。 根据您的监视需求,可以编写一个非常一般的配置文件,用来订阅对工作流进行的一小组高级状态更改。 相反,也可以创建一个非常详细的配置文件,其生成的事件足够丰富,可在以后重新构造详细的执行流。
跟踪配置文件将其自身列为标准 .NET Framework 配置文件中的 XML 元素或在代码中指定的 XML 元素。 下面的示例摘自配置文件中的 .NET Framework 4.6.1 跟踪配置文件,跟踪参与者可利用它订阅 Started
和 Completed
工作流事件。
<system.serviceModel>
...
<tracking>
<profiles>
<trackingProfile name="Sample Tracking Profile">
<workflow activityDefinitionId="*">
<workflowInstanceQueries>
<workflowInstanceQuery>
<states>
<state name="Started"/>
<state name="Completed"/>
</states>
</workflowInstanceQuery>
</workflowInstanceQueries>
</workflow>
</trackingProfile>
</profiles>
</tracking>
...
</system.serviceModel>
下面的示例演示使用代码创建的等效跟踪配置文件。
TrackingProfile profile = new TrackingProfile()
{
Name = "CustomTrackingProfile",
Queries =
{
new WorkflowInstanceQuery()
{
// Limit workflow instance tracking records for started and
// completed workflow states.
States = { WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
}
}
};
利用 ImplementationVisibility 特性,可以通过跟踪配置文件中的可见性模式筛选跟踪记录。 复合活动是一个顶级活动,其中包含构成其实现的其他活动。 可见性模式指定工作流活动中的复合活动发出的跟踪记录,这些跟踪记录用于指定是否跟踪构成实现的活动。 可见性模式在跟踪配置文件级别应用。 工作流中单个活动的跟踪记录的筛选由跟踪配置文件中的查询控制。 有关详细信息,请参阅本文档中的 “跟踪配置文件查询类型 ”部分。
跟踪配置文件中的 implementationVisibility
属性指定了两种可见性模式:RootScope
和 All
。 在复合活动不是工作流根的情况下,使用 RootScope
模式可抑制与活动执行有关的活动的跟踪记录。 这意味着,如果将使用其他活动实现的活动添加到工作流中,并且 implementationVisibility
设置为 RootScope,则只跟踪该复合活动中的顶级活动。 如果一个活动是工作流的根源,那么该活动的实现就是工作流本身,同时会为构成实现的活动发出跟踪记录。 使用“所有”模式允许针对根活动及其所有复合活动发出所有跟踪记录。
例如,假设 MyActivity 是一个复合活动,其实现包含两个活动: Activity1 和 Activity2。 当此活动被添加到工作流并使用跟踪配置文件启用跟踪,且 implementationVisibility
设置为 RootScope
时,仅会为 MyActivity 发出跟踪记录。 但是,不会为 Activity1 和 Activity2 发出任何记录。
但是,如果将 implementationVisibility
跟踪配置文件的属性设置为 All
,则不仅针对 MyActivity 发出跟踪记录,还会针对 Activity1 和 Activity2 发出跟踪记录。
该 implementationVisibility
标志适用于以下跟踪记录类型:
活动状态记录
FaultPropagationRecord
CancelRequestedRecord
ActivityScheduledRecord
注释
implementationVisibility 设置无法筛选出活动实现发出的 CustomTrackingRecord。
在代码中,按如下所示在跟踪配置文件中将 implementationVisibility
功能指定为 RootScope:
TrackingProfile sampleTrackingProfile = new TrackingProfile()
{
Name = "Sample Tracking Profile",
ImplementationVisibility = ImplementationVisibility.RootScope
};
在配置文件中,按如下所示在跟踪配置文件中将 implementationVisibility
功能指定为 All:
<tracking>
<profiles>
<trackingProfile name="Shipping Monitoring" implementationVisibility="All">
<workflow activityDefinitionId="*">
...
</workflow>
</trackingProfile>
</profiles>
</tracking>
跟踪配置文件中的 ImplementationVisibility
设置是可选的。 默认情况下,其值设置为 RootScope
。 此外,该特性的值还区分大小写。
跟踪配置文件查询类型
跟踪配置文件组织为跟踪记录的声明性订阅,利用这些订阅可以查询特定跟踪记录的工作流运行时。 有多种查询类型可用于订阅不同的对象类 TrackingRecord 。 可以通过配置或代码指定跟踪配置文件。 下面是最常见的查询类型:
WorkflowInstanceQuery - 使用它来跟踪工作流实例生命周期的变化,就像之前演示的
Started
和Completed
一样。 WorkflowInstanceQuery 用于订阅以下 TrackingRecord 对象:可以在类中 WorkflowInstanceStates 指定可订阅的状态。
以下示例显示了用于通过
Started
订阅WorkflowInstanceQuery实例状态的工作流实例级跟踪记录的配置或代码。<workflowInstanceQueries> <workflowInstanceQuery> <states> <state name="Started"/> </states> </workflowInstanceQuery> </workflowInstanceQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new WorkflowInstanceQuery() { States = { WorkflowInstanceStates.Started} } } };
ActivityStateQuery - 用于跟踪构成工作流实例的活动的生命周期更改。 例如,你可能希望在工作流实例中记录“发送电子邮件”活动每次完成时的情况。 TrackingParticipant 需要用该查询来订阅 ActivityStateRecord 对象。 可以订阅的状态已在 ActivityStates 中指定。
下面的示例演示使用 ActivityStateQuery 订阅
SendEmailActivity
活动的活动状态跟踪记录所使用的配置和代码。<activityStateQueries> <activityStateQuery activityName="SendEmailActivity"> <states> <state name="Closed"/> </states> </activityStateQuery> </activityStateQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new ActivityStateQuery() { ActivityName = "SendEmailActivity", States = { ActivityStates.Closed } } } };
注释
如果多个 activityStateQuery 元素具有相同的名称,则跟踪配置文件中仅使用最后一个元素中的状态。
ActivityScheduledQuery - 此查询允许您跟踪由父活动安排执行的活动。 TrackingParticipant 需要用该查询来订阅 ActivityScheduledRecord 对象。
下面的示例演示使用
SendEmailActivity
订阅与安排执行的 ActivityScheduledQuery 子活动相关的记录所使用的配置和代码。<activityScheduledQueries> <activityScheduledQuery activityName="ProcessNotificationsActivity" childActivityName="SendEmailActivity" /> </activityScheduledQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new ActivityScheduledQuery() { ActivityName = "ProcessNotificationsActivity", ChildActivityName = "SendEmailActivity" } } };
FaultPropagationQuery - 使用此方法跟踪活动中发生的故障的处理。 TrackingParticipant 需要用该查询来订阅 FaultPropagationRecord 对象。
以下示例显示了使用 FaultPropagationQuery 订阅与故障传播相关记录的配置和代码。
<faultPropagationQueries> <faultPropagationQuery faultSourceActivityName="SendEmailActivity" faultHandlerActivityName="NotificationsFaultHandler" /> </faultPropagationQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new FaultPropagationQuery() { FaultSourceActivityName = "SendEmailActivity", FaultHandlerActivityName = "NotificationsFaultHandler" } } };
CancelRequestedQuery - 用于跟踪父活动取消子活动的请求。 TrackingParticipant 需要用该查询来订阅 CancelRequestedRecord 对象。
下面的示例演示使用 CancelRequestedQuery 订阅与活动取消相关的记录所使用的配置和代码。
<cancelRequestedQueries> <cancelRequestedQuery activityName="ProcessNotificationsActivity" childActivityName="SendEmailActivity" /> </cancelRequestedQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new CancelRequestedQuery() { ActivityName = "ProcessNotificationsActivity", ChildActivityName = "SendEmailActivity" } } };
CustomTrackingQuery - 使用此函数跟踪在代码活动中定义的事件。 TrackingParticipant 需要用该查询来订阅 CustomTrackingRecord 对象。
以下示例展示了使用 CustomTrackingQuery 订阅自定义跟踪记录相关记录的配置和代码。
<customTrackingQueries> <customTrackingQuery name="EmailAddress" activityName="SendEmailActivity" /> </customTrackingQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new CustomTrackingQuery() { Name = "EmailAddress", ActivityName = "SendEmailActivity" } } };
BookmarkResumptionQuery - 用于跟踪工作流实例中书签的重新启动。 TrackingParticipant 需要用该查询来订阅 BookmarkResumptionRecord 对象。
下面的示例演示使用 BookmarkResumptionQuery 订阅与书签恢复相关的记录所使用的配置和代码。
<bookmarkResumptionQueries> <bookmarkResumptionQuery name="SentEmailBookmark" /> </bookmarkResumptionQueries>
TrackingProfile sampleTrackingProfile = new TrackingProfile() { Name = "Sample Tracking Profile", Queries = { new BookmarkResumptionQuery() { Name = "sentEmailBookmark" } } };
批注
通过批注,可以使用可在生成时后配置的某个值任意标记跟踪记录。 例如,你可能希望多个工作流中的多个跟踪记录用“邮件服务器”=“Mail Server1”进行标记。 这样就可以在以后查询跟踪记录时轻松查找具有此标记的所有记录。
为此,将注释添加到跟踪查询,如以下示例所示。
<activityStateQuery activityName="SendEmailActivity">
<states>
<state name="Closed"/>
</states>
<annotations>
<annotation name="MailServer" value="Mail Server1"/>
</annotations>
</activityStateQuery>
如何创建跟踪配置文件
跟踪查询元素用于通过使用 XML 配置文件或 .NET Framework 4.6.1 代码创建跟踪配置文件。 以下是使用配置文件创建跟踪配置文件的示例。
<system.serviceModel>
<tracking>
<profiles>
<trackingProfile name="Sample Tracking Profile ">
<workflow activityDefinitionId="*">
<!--Specify the tracking profile query elements to subscribe for tracking records-->
</workflow>
</trackingProfile>
</profiles>
</tracking>
</system.serviceModel>
警告
对于使用工作流服务主机的 WF,通常通过配置文件来创建跟踪配置。 也可以通过代码使用跟踪配置文件和跟踪查询 API 来创建跟踪配置文件。
配置为 XML 配置文件的个人资料会通过行为扩展应用于跟踪参与者。 已将其添加到 WorkflowServiceHost,如后面的 “为工作流配置跟踪”部分所述。
主机发出的跟踪记录的详尽程度取决于跟踪配置文件中的具体设置。 跟踪参与者通过向跟踪配置文件添加查询来订阅跟踪记录。 若要订阅所有跟踪记录,跟踪配置文件需要在每个查询的名称字段中使用“*”指定所有跟踪查询。
下面是跟踪配置文件的一些常见示例。
用于获取工作流实例记录和错误的跟踪配置文件。
<trackingProfile name="Instance and Fault Records"> <workflow activityDefinitionId="*"> <workflowInstanceQueries> <workflowInstanceQuery> <states> <state name="*" /> </states> </workflowInstanceQuery> </workflowInstanceQueries> <activityStateQueries> <activityStateQuery activityName="*"> <states> <state name="Faulted"/> </states> </activityStateQuery> </activityStateQueries> </workflow> </trackingProfile>
用于获取所有自定义跟踪记录的跟踪配置文件。
<trackingProfile name="Instance_And_Custom_Records"> <workflow activityDefinitionId="*"> <customTrackingQueries> <customTrackingQuery name="*" activityName="*" /> </customTrackingQueries> </workflow> </trackingProfile>