##// END OF EJS Templates
code cleanup and refactoring
code cleanup and refactoring

File last commit:

r281:e0916ddc9950 v3
r281:e0916ddc9950 v3
Show More
Trace.cs
161 lines | 6.4 KiB | text/x-csharp | CSharpLexer
// enable System.Diagnostics trace methods
#define TRACE
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Implab.Diagnostics {
public static class Trace<T> {
static Lazy<TraceSource> _traceSource = new Lazy<TraceSource>(CreateChannel, LazyThreadSafetyMode.ExecutionAndPublication);
static int _nextId;
static TraceSource CreateChannel() {
var id = Interlocked.Increment(ref _nextId);
return new TraceSource(typeof(T).Name);
}
public static TraceSource TraceSource { get { return _traceSource.Value; } }
public static IDisposable Subscribe() {
throw new NotImplementedException();
}
#if NETFX_TRACE_BUG
readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>();
#endif
/// <summary>
/// Starts the logical operation nested to the current operation nested to the current one.
/// </summary>
public static void StartLogicalOperation() {
Trace.CorrelationManager.StartLogicalOperation();
}
/// <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);
}
#else
public static void StartLogicalOperation(object name) {
Trace.CorrelationManager.StartLogicalOperation(name);
}
#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) {
}
/// <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);
}
}
}