Trace.cs
132 lines
| 5.5 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r212 | using System; | ||
using System.Collections.Generic; | ||||
using System.Diagnostics; | ||||
using System.Linq; | ||||
using System.Text; | ||||
cin
|
r255 | using System.Threading; | ||
cin
|
r212 | using System.Threading.Tasks; | ||
namespace Implab.Diagnostics { | ||||
public static class Trace<T> { | ||||
cin
|
r255 | public static TraceSource TraceSource { get; } = new TraceSource(typeof(T).Name); | ||
#if NETFX_TRACE_BUG | ||||
readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); | ||||
#endif | ||||
cin
|
r212 | /// <summary> | ||
/// Starts the logical operation nested to the current operation nested to the current one. | ||||
/// </summary> | ||||
public static void StartLogicalOperation() { | ||||
cin
|
r252 | Trace.CorrelationManager.StartLogicalOperation(); | ||
cin
|
r212 | |||
} | ||||
/// <summary> | ||||
/// Starts the logical operation with the specified name, this name is usefull in logs. | ||||
/// </summary> | ||||
/// <param name="name">Name.</param> | ||||
cin
|
r255 | #if NETFX_TRACE_BUG | ||
public static void StartLogicalOperation(object name) { | ||||
m_currentOperation.Value = name; | ||||
cin
|
r253 | Trace.CorrelationManager.StartLogicalOperation(name); | ||
cin
|
r212 | } | ||
cin
|
r255 | #else | ||
public static void StartLogicalOperation(object name) { | ||||
Trace.CorrelationManager.StartLogicalOperation(name); | ||||
} | ||||
#endif | ||||
cin
|
r212 | |||
/// <summary> | ||||
/// Ends the logical operation and restores the previous one. | ||||
/// </summary> | ||||
cin
|
r252 | public static void StopLogicalOperation() { | ||
Trace.CorrelationManager.StopLogicalOperation(); | ||||
cin
|
r212 | } | ||
/// <summary> | ||||
/// Writes an informational message. | ||||
/// </summary> | ||||
/// <param name="format">Format.</param> | ||||
/// <param name="arguments">Arguments.</param> | ||||
[Conditional("TRACE")] | ||||
public static void Log(string format, params object[] arguments) { | ||||
cin
|
r253 | TraceSource.TraceEvent(TraceEventType.Information, 0, format, arguments); | ||
cin
|
r212 | } | ||
/// <summary> | ||||
/// Writes a warning message. | ||||
/// </summary> | ||||
/// <param name="format">Format.</param> | ||||
/// <param name="arguments">Arguments.</param> | ||||
[Conditional("TRACE")] | ||||
public static void Warn(string format, params object[] arguments) { | ||||
cin
|
r253 | TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments); | ||
cin
|
r212 | } | ||
[Conditional("TRACE")] | ||||
public static void Error(string format, params object[] arguments) { | ||||
cin
|
r253 | TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments); | ||
cin
|
r212 | } | ||
[Conditional("TRACE")] | ||||
public static void Error(Exception err) { | ||||
cin
|
r253 | TraceSource.TraceData(TraceEventType.Error, 0, err); | ||
} | ||||
/// <summary> | ||||
/// This method save the current activity, and transfers to the specified activity, | ||||
/// emits <see cref="TraceEventType.Start"/> and returns a scope of the new | ||||
/// activity. | ||||
/// </summary> | ||||
/// <param name="activityName">The name of the new activity/</param> | ||||
/// <param name="activityId">The identifier of the activity to which | ||||
/// the control will be transferred</param> | ||||
/// <returns>A scope of the new activity, dispose it to transfer | ||||
/// the control back to the original activity.</returns> | ||||
public static ActivityScope TransferActivity(string activityName, Guid activityId) { | ||||
var prev = Trace.CorrelationManager.ActivityId; | ||||
TraceSource.TraceTransfer(0, "Transfer", activityId); | ||||
Trace.CorrelationManager.ActivityId = activityId; | ||||
TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); | ||||
return new ActivityScope(TraceSource, prev, 0, activityName); | ||||
} | ||||
/// <summary> | ||||
/// Emits <see cref="TraceEventType.Start"/> and returns a scope of the | ||||
/// activity. | ||||
/// </summary> | ||||
/// <param name="activityName">The name of the activity to start</param> | ||||
/// <returns>A scope of the new activity, dispose it to emit | ||||
/// <see cref="TraceEventType.Stop"/> for the current activity.</returns> | ||||
public static ActivityScope StartActivity(string activityName) { | ||||
if (Trace.CorrelationManager.ActivityId == Guid.Empty) | ||||
Trace.CorrelationManager.ActivityId = Guid.NewGuid(); | ||||
var prev = Trace.CorrelationManager.ActivityId; | ||||
TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); | ||||
return new ActivityScope(TraceSource, prev, 0, activityName); | ||||
} | ||||
/// <summary> | ||||
/// Creates new <see cref="LogicalOperation(string)"/> and calls | ||||
/// to <see cref="CorrelationManager.StartLogicalOperation(object)"/> | ||||
/// passing the created operation as identity. Calls | ||||
/// <see cref="TraceSource.TraceData(TraceEventType, int, object)"/> | ||||
/// to notify listeners on operation start. | ||||
/// </summary> | ||||
/// <param name="name">The name of the logical operation.</param> | ||||
/// <returns>Logical operation scope, disposing it will stop | ||||
/// logical operation and notify trace listeners.</returns> | ||||
public static LogicalOperationScope LogicalOperation(string name) { | ||||
var operation = new LogicalOperation(name); | ||||
TraceSource.TraceData(TraceEventType.Information, TraceEventCodes.StartLogicalOperation, operation); | ||||
cin
|
r255 | StartLogicalOperation(operation); | ||
cin
|
r253 | return new LogicalOperationScope(TraceSource, operation); | ||
cin
|
r212 | } | ||
} | ||||
} | ||||