I was having some problems today with my workflows, and I needed to get some more information. Of course, tracing is the obvious solution. I didn’t even know where to begin putting trace points in my code, so I thought I would jack up the integrated workflow tracing and see if that gave me any ideas. Now how to do that? I just can’t remember. Google to the rescue!
Of course, you get the documentation sample:
<system.diagnostics>
<switches>
<add name="System.Workflow LogToFile" value="1" />
<add name="Host" value="Error" />
<add name="Runtime" value="Warning" />
<add name="Tracking" value="Info" />
<add name="Activity" value="All" />
</switches>
<trace autoflush="true" indentsize="4">
</trace>
</system.diagnostics>
Uh…Ok. But where does that go? It goes to a file (WorkflowTrace.log) in your program exe directory. And it’s plain text. How to integrate this into the Service Model tracing I already have established for my project?
<system.diagnostics>
<switches>
<add name="System.Workflow LogToTraceListeners" value="1" />
<add name="Host" value="Error" />
<add name="Runtime" value="Warning" />
<add name="Tracking" value="Info" />
<add name="Activity" value="All" />
</switches>
<trace autoflush="true" indentsize="4">
</trace>
</system.diagnostics>
Uh…Ok. But what listeners is it going to? For me…none. It’s not explicitly stated, so sometimes I don’t explicitly do it. We have to manually add a trace listener in the trace configuration section, not sources. So our configuration becomes:
<system.diagnostics>
<switches>
<add name="System.Workflow LogToTraceListeners" value="1" />
<add name="Host" value="Error" />
<add name="Runtime" value="Warning" />
<add name="Tracking" value="Info" />
<add name="Activity" value="All" />
</switches>
<trace autoflush="true" indentsize="4">
<listeners>
<add
initializeData="c:\logs\test.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener"
traceOutputOptions="Timestamp">
</add>
</listeners>
</trace>
</system.diagnostics>
Ok. One step closer to the edge. But, you can eliminate the LogToTraceListeners line altogether, and use each switch name as a source. This keeps a more consistent Service Model e2e tracing configuration:
<system.diagnostics>
<switches>
<!--<add name="System.Workflow LogToFile" value="1" />
<add name="System.Workflow LogToTraceListeners" value="1" />-->
<add name="System.Workflow.Runtime" value="Warning" />
<add name="System.Workflow.Runtime.Hosting" value="Warning" />
<add name="System.Workflow.Runtime.Tracking" value="Warning" />
<add name="System.Workflow.Activities" value="Warning" />
<add name="System.Workflow.Activities.Rules" value="Warning" />
</switches>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Warning" propagateActivity="true">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default" />
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Workflow">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Workflow.Runtime">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Workflow.Runtime.Hosting">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Workflow.Runtime.Tracking">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Workflow.Activities">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="c:\logs\test.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener"
traceOutputOptions="Timestamp" />
</sharedListeners>
</system.diagnostics>
Now, a single .svclog file contains WCF Service Model tracing, as well as Workflow tracing, including activity tracing.
One word of warning: Again, blindly copying and pasting code from other blogs led me to use “Verbose” as the switch value for the workflow switches. You know what? Nothing traced at all because Verbose is not a valid switch value. Yeah…I wish I had that 30 minutes of my life back.
The proper switch value for verbose output is All, not Verbose.
Don’t say I didn’t warn you. It is documented incorrectly out there.
f15c998f-3c2c-4e3e-bf46-f8b214fdc020|0|.0
Development
workflow | visual studio