Trace.cs
198 lines
| 8.0 KiB
| text/x-csharp
|
CSharpLexer
|
|
r289 | // enable System.Diagnostics trace methods | ||
| #define TRACE | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
|
|
r295 | |||
| #if NETFX_TRACE_BUG | ||||
| using System.Threading; | ||||
| #endif | ||||
|
|
r289 | |||
| namespace Implab.Diagnostics { | ||||
| /// <summary> | ||||
| /// Static class which creates an individual <see cref="TraceSource"/> for | ||||
| /// the type specified in the parameter <typeparamref name="T"/> and uses | ||||
| /// it to perform logging operations. | ||||
| /// </summary> | ||||
| /// <typeparam name="T">The type for which tracing is demanded.</typeparam> | ||||
| public static class Trace<T> { | ||||
| readonly static Lazy<TraceSource> _trace = new Lazy<TraceSource>(() => TraceSourceChannel<T>.Default.Source); | ||||
| /// <summary> | ||||
| /// The <see cref="TraceSource"/> associated with the current class. | ||||
| /// TraceSource is created using <see cref="TraceSourceChannel{T}"/>. | ||||
| /// </summary> | ||||
| public static TraceSource TraceSource { get { return _trace.Value; } } | ||||
| #if NETFX_TRACE_BUG | ||||
| // AsyncLocal will store value inside the current execution context | ||||
| // and will force it to be copied... not a very effective solution. | ||||
| readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); | ||||
| #endif | ||||
| /// <summary> | ||||
| /// 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. | ||||
| /// </summary> | ||||
| public static bool TraceInformation { | ||||
| get { | ||||
| return TraceSource.Switch.ShouldTrace(TraceEventType.Information); | ||||
| } | ||||
| } | ||||
| /// <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); | ||||
| } | ||||
| } | ||||
| /// <summary> | ||||
| /// Starts the logical operation with the specified name, this name is usefull in logs. | ||||
| /// </summary> | ||||
| /// <param name="name">Name.</param> | ||||
| #if NETFX_TRACE_BUG | ||||
| public static void StartLogicalOperation(object name) { | ||||
| m_currentOperation.Value = name; | ||||
| Trace.CorrelationManager.StartLogicalOperation(name); | ||||
| } | ||||
| /// <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(); | ||||
| } | ||||
| #else | ||||
| public static void StartLogicalOperation(object name) { | ||||
| Trace.CorrelationManager.StartLogicalOperation(name); | ||||
| } | ||||
| /// <summary> | ||||
| /// Starts the logical operation nested to the current operation nested to the current one. | ||||
| /// </summary> | ||||
| public static void StartLogicalOperation() { | ||||
| Trace.CorrelationManager.StartLogicalOperation(); | ||||
| } | ||||
| #endif | ||||
| /// <summary> | ||||
| /// Ends the logical operation and restores the previous one. | ||||
| /// </summary> | ||||
| public static void StopLogicalOperation() { | ||||
| Trace.CorrelationManager.StopLogicalOperation(); | ||||
| } | ||||
| /// <summary> | ||||
| /// 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) { | ||||
| TraceSource.TraceEvent(TraceEventType.Verbose, 0, format, arguments); | ||||
| } | ||||
| /// <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) { | ||||
| TraceSource.TraceEvent(TraceEventType.Information, 0, format, arguments); | ||||
| } | ||||
| /// <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) { | ||||
| TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments); | ||||
| } | ||||
| /// <summary> | ||||
| /// Writes a error message. | ||||
| /// </summary> | ||||
| /// <param name="format">Format.</param> | ||||
| /// <param name="arguments">Arguments.</param> | ||||
| public static void Error(string format, params object[] arguments) { | ||||
| TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments); | ||||
| } | ||||
| public static void Error(Exception err) { | ||||
| 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); | ||||
| StartLogicalOperation(operation); | ||||
| return new LogicalOperationScope(TraceSource, operation); | ||||
| } | ||||
| } | ||||
| } | ||||
