Trace.cs
199 lines
| 8.0 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r281 | // enable System.Diagnostics trace methods | ||
#define TRACE | ||||
using System; | ||||
cin
|
r212 | 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 { | ||||
cin
|
r286 | /// <summary> | ||
/// Static class which creates an individual <see cref="TraceSource"/> for | ||||
cin
|
r287 | /// the type specified in the parameter <typeparamref name="T"/> and uses | ||
/// it to perform logging operations. | ||||
cin
|
r286 | /// </summary> | ||
/// <typeparam name="T">The type for which tracing is demanded.</typeparam> | ||||
cin
|
r212 | public static class Trace<T> { | ||
cin
|
r286 | readonly static Lazy<TraceSource> _trace = new Lazy<TraceSource>(() => TraceSourceChannel<T>.Default.Source); | ||
cin
|
r281 | |||
cin
|
r287 | /// <summary> | ||
/// The <see cref="TraceSource"/> associated with the current class. | ||||
/// TraceSource is created using <see cref="TraceSourceChannel{T}"/>. | ||||
/// </summary> | ||||
cin
|
r286 | public static TraceSource TraceSource { get { return _trace.Value; } } | ||
cin
|
r281 | |||
cin
|
r255 | #if NETFX_TRACE_BUG | ||
cin
|
r287 | // AsyncLocal will store value inside the current execution context | ||
// and will force it to be copied... not a very effective solution. | ||||
cin
|
r255 | readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); | ||
#endif | ||||
cin
|
r212 | /// <summary> | ||
cin
|
r286 | /// If this property is set then <see cref="Debug(string, object[])"/> will produce output. | ||
/// </summary> | ||||
public static bool TraceVerbose { | ||||
get { | ||||
return TraceSource.Switch.ShouldTrace(TraceEventType.Verbose); | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// If this property is set then <see cref="Log(string, object[])"/> will produce output. | ||||
cin
|
r212 | /// </summary> | ||
cin
|
r286 | public static bool TraceInformation { | ||
get { | ||||
return TraceSource.Switch.ShouldTrace(TraceEventType.Information); | ||||
} | ||||
} | ||||
cin
|
r212 | |||
cin
|
r286 | /// <summary> | ||
/// If this property is set then <see cref="Warn(string, object[])"/> will produce output. | ||||
/// </summary> | ||||
public static bool TraceWarnings { | ||||
get { | ||||
return TraceSource.Switch.ShouldTrace(TraceEventType.Warning); | ||||
} | ||||
cin
|
r212 | } | ||
cin
|
r286 | |||
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
|
r286 | |||
/// <summary> | ||||
/// Starts the logical operation nested to the current operation nested to the current one. | ||||
/// </summary> | ||||
public static void StartLogicalOperation() { | ||||
m_currentOperation.Value = new object(); | ||||
Trace.CorrelationManager.StartLogicalOperation(); | ||||
} | ||||
cin
|
r255 | #else | ||
public static void StartLogicalOperation(object name) { | ||||
Trace.CorrelationManager.StartLogicalOperation(name); | ||||
} | ||||
cin
|
r286 | |||
/// <summary> | ||||
/// Starts the logical operation nested to the current operation nested to the current one. | ||||
/// </summary> | ||||
public static void StartLogicalOperation() { | ||||
Trace.CorrelationManager.StartLogicalOperation(); | ||||
} | ||||
cin
|
r255 | #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> | ||||
cin
|
r280 | /// Writes a debug message. | ||
/// </summary> | ||||
/// <param name="format">Format.</param> | ||||
/// <param name="arguments">Arguments.</param> | ||||
[Conditional("DEBUG")] | ||||
public static void Debug(string format, params object[] arguments) { | ||||
cin
|
r286 | TraceSource.TraceEvent(TraceEventType.Verbose, 0, format, arguments); | ||
cin
|
r280 | } | ||
/// <summary> | ||||
cin
|
r212 | /// 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> | ||||
public static void Warn(string format, params object[] arguments) { | ||||
cin
|
r253 | TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments); | ||
cin
|
r212 | } | ||
cin
|
r280 | /// <summary> | ||
/// Writes a error message. | ||||
/// </summary> | ||||
/// <param name="format">Format.</param> | ||||
/// <param name="arguments">Arguments.</param> | ||||
cin
|
r212 | public static void Error(string format, params object[] arguments) { | ||
cin
|
r253 | TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments); | ||
cin
|
r212 | } | ||
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; | ||||
cin
|
r286 | |||
cin
|
r253 | 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 | } | ||
} | ||||
} | ||||