|
|
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());
|
|
|
}*/
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|