using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Implab.Diagnostics { public class LogContext { LogicalOperation m_currentOperation; readonly LogicalOperation m_traceBound; readonly int m_threadId; readonly LogContext m_parent; readonly static object _consoleLock = new object(); [ThreadStatic] static LogContext _current; public static LogContext Current { get { if (_current == null) _current = new LogContext(); return _current; } } LogContext(LogContext context) { if (context == null) throw new ArgumentNullException("context"); m_parent = context; m_currentOperation = context.CurrentOperation; m_traceBound = context.CurrentOperation; m_threadId = Thread.CurrentThread.ManagedThreadId; TraceEvent(TraceEventType.Transfer, String.Empty); } LogContext() { m_currentOperation = new LogicalOperation(); m_traceBound = m_currentOperation; m_threadId = Thread.CurrentThread.ManagedThreadId; } public static void Transfer(LogContext from) { _current = from == null ? new LogContext() : new LogContext(from); } public LogContext ParentContext { get { return m_parent; } } public LogicalOperation CurrentOperation { get { return m_currentOperation; } } public LogicalOperation TraceBound { get { return m_traceBound; } } public int ThreadId { get { return m_threadId; } } public void StartLogicalOperation() { StartLogicalOperation(null); } public void StartLogicalOperation(string name) { TraceEvent(TraceEventType.OperationStarted, "{0}", name); m_currentOperation = new LogicalOperation(name, m_currentOperation); } public void EndLogicalOperation() { if (m_traceBound == m_currentOperation) { TraceEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace"); } else { var op = m_currentOperation; m_currentOperation = m_currentOperation.Parent; TraceEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration); } } public void TraceEvent(TraceEventType type, string format, params object[] args) { /*var msg = new StringBuilder(); for (int i = 0; i < CurrentOperation.Level; i++) msg.Append(" "); msg.Append(type); msg.AppendFormat("[{0}]: ",m_threadId); msg.AppendFormat(format, args); lock (_consoleLock) { Console.ForegroundColor = (ConsoleColor)(m_threadId % 15 + 1); Console.WriteLine(msg.ToString()); }*/ } } }