Diagnostic Traces
Traces are the publishing of specific messages that are generated during application execution. When using tracing, you must have a mechanism for collecting and recording the messages that are sent. Trace messages are received by listeners. The purpose of a listener is to collect, store, and route tracing messages. Listeners direct the tracing output to an appropriate target, such as a log, window, or text file.
One such listener, the DefaultTraceListener, is automatically created and initialized when tracing is enabled. If you want trace output to be directed to any additional sources, you must create and initialize additional trace listeners. The listeners you create should reflect your individual needs. For example, you might want a text record of all trace output. In this case, you would create a listener that wrote all output to a new text file when enabled. On the other hand, you might only want to view output during application execution. In that case, you might create a listener that directed all output to a console window. The EventLogTraceListener can direct trace output to an event log, and the TextWriterTraceListener can write trace output to a stream.
Enabling Tracing
To enable traces during transaction processing, you should edit your application’s configuration file. The following is an example.
<configuration>
<system.diagnostics>
<sources>
<source name="System.Transactions" switchValue="Warning">
<listeners>
<add name="tx"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "tx.log" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
System.Transactions traces are written to the source named "System.Transactions". You can use add
to specify the name and type of the trace listener you want to use. In our example configuration, we named the Listener "tx" and added the standard .NET Framework trace listener (XmlWriterTraceListener) as the type we want to use. Use initializeData
to set the name of the log file for that listener. In addition, you can substitute a fully qualified path for a simple file name.
Each trace message type is assigned a level to indicate its degree of importance. If the app-domain’s trace level is equal or lower than the level of an event type, then that message is generated. The tracing level is controlled by the switchValue
setting in the configuration file. The levels that are associated with diagnostic trace messages are defined in the following table.
Trace Level | Description |
---|---|
Critical | Serious failures, such as the following, have occurred: - An error that can cause an immediate loss in user functionality. - An event that requires an administrator to take action to avoid loss of functionality. - Code hangs. - This tracing level can also provide sufficient context for interpreting other critical traces. This can help to identify the sequence of operations leading to a serious failure. |
Error | An error (for example, invalid configuration or network behavior) has occurred that can result in a loss of user functionality. |
Warning | A condition exists that can subsequently result in an error or critical failure (for example, allocation failing or approaching a limit). Normal processing of errors from user code (for example, transaction aborted, timeouts, authentication failed) can also generate a warning. |
Information | Messages helpful for monitoring and diagnosing system status, measuring performance, or profiling are generated. These can include transaction and enlistment lifetime events, such as a transaction being created or committed, the crossing of a significant boundary, or the allocation of significant resources. A developer can then utilize such information for capacity planning and performance management. |
Trace Codes
The following table lists the trace codes that are generated by the System.Transactions infrastructure. Included in the table are the trace code identifier, the EventType enumeration level for the trace, and the extra data contained in the TraceRecord for the trace. In addition, the corresponding trace level of the trace is also stored in the TraceRecord.
TraceCode | EventType | Extra data in TraceRecord |
---|---|---|
TransactionCreated | Info | TransactionTraceId |
TransactionPromoted | Info | Local TransactionTraceId, Distributed TransactionTraceId |
EnlistmentCreated | Info | TransactionTraceId, EnlistmentTraceId, EnlistmentType (durable/volatile), EnlistmentOptions |
EnlistmentCallbackNegative | Warning | TransactionTraceId, EnlistmentTraceId, Callback (forcerollback/aborted/indoubt) |
TransactionRollbackCalled | Warning | TransactionTraceId |
TransactionAborted | Warning | TransactionTraceId |
TransactionInDoubt | Warning | TransactionTraceId |
TransactionScopeCreated | Info | TransactionScopeResult, which can be the following: - New transaction. - Transaction passed. - Dependent transaction passed. - Using current transaction. - No transaction. new current TransactionTraceId |
TransactionScopeDisposed | Info | TransactionTraceId of the scope’s "expected" current transaction. |
TransactionScopeIncomplete | Warning | TransactionTraceId of the scope’s "expected" current transaction. |
TransactionScopeNestedIncorrectly | Warning | TransactionTraceId of the scope’s "expected" current transaction. |
TransactionScopeCurrentTransactionChanged | Warning | Old current TransactionTraceId, other TransactionTraceId |
TransactionScopeTimeout | Warning | TransactionTraceId of the scope’s "expected" current transaction. |
DependentCloneCreated | Info | TransactionTraceId, type of dependent transaction created (RollbackIfNotComplete/BlockCommitUntilComplete) |
DependentCloneComplete | Info | TransactionTraceId |
RecoveryComplete | Info | Resource Manager GUID (from base) |
Reenlist | Info | Resource Manager GUID (from base) |
TransactionSerialized | Info | TransactionTraceId. |
TransactionException | Error | Exception message |
InvalidOperationException | Error | Exception message |
InternalError | Critical | Exception message |
TransferEvent | When a transaction is deserialized, or promoted from a System.Transactions transaction to a distributed one, the current ActivityID from the ExecutionContext and the distributed transaction ID are written. When the DTC calls back into managed code, the distributed transaction ID is set as the ActivityID in the ExecutionContext for the duration of the callback. |
|
ConfiguredDefaultTimeoutAdjusted | Warning | No extra data |
TransactionTimeout | Warning | The TransactionTraceId of the transaction being timed out. |
The XML schema for each of the preceding extra data items has the following format.
TransactionTraceIdentifier
<TransactionTraceIdentifier>
<TransactionIdentifier >
string representation of transaction id
</TransactionIdentifier>
< CloneIdentifier >
the clone id number
</CloneIdentifier>
</TransactionTraceIdentifier>
EnlistmentTraceIdentifier
<EnlistmentTraceIdentifier>
<ResourceManagerId>
string form of guid
</ResourceManagerId>
<TransactionTraceIdentifier>
<TransactionIdentifier >
string representation of transaction id
</TransactionIdentifier>
<CloneIdentifier >
the clone id number
</CloneIdentifier>
<TransactionTraceIdentifier>
<EnlistmentIdentifier>
the enlistment id number
</EnlistmentIdentifier>
</EnlistmentTraceIdentifier>
Resource Manager Identifier
<ResourceManagerId>
string form of guid
</ResourceManagerId>
Security Issues For Tracing
When you as an administrator turn on tracing, sensitive information might be written to a trace log that is publicly viewable by default. To mitigate any possible security threat, you should consider storing the trace log in a secure location controlled by share and file system access permissions.