36
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.Linq;
|
|
4 using System.Text;
|
|
5 using System.Threading;
|
|
6 using System.Threading.Tasks;
|
|
7
|
|
8 namespace Implab.Diagnostics {
|
|
9 public class TraceContext {
|
|
10 LogicalOperation m_currentOperation;
|
|
11 readonly LogicalOperation m_traceBound;
|
|
12 readonly int m_threadId;
|
|
13 readonly TraceContext m_parent;
|
|
14
|
|
15 readonly static object _consoleLock = new object();
|
|
16
|
|
17 [ThreadStatic]
|
|
18 static TraceContext _current;
|
|
19
|
|
20 public static TraceContext Current {
|
|
21 get {
|
|
22 if (_current == null)
|
|
23 _current = new TraceContext();
|
|
24 return _current;
|
|
25 }
|
|
26 }
|
|
27
|
|
28 TraceContext(TraceContext context) {
|
|
29 if (context == null)
|
|
30 throw new ArgumentNullException("context");
|
|
31
|
|
32 m_parent = context;
|
|
33 m_currentOperation = context.CurrentOperation;
|
|
34 m_traceBound = context.CurrentOperation;
|
|
35 m_threadId = Thread.CurrentThread.ManagedThreadId;
|
|
36
|
37
|
37 LogEvent(TraceEventType.Transfer, "FORK {0}", context.ThreadId);
|
36
|
38 }
|
|
39
|
|
40 TraceContext() {
|
|
41 m_currentOperation = new LogicalOperation();
|
|
42 m_traceBound = m_currentOperation;
|
|
43 m_threadId = Thread.CurrentThread.ManagedThreadId;
|
|
44 }
|
|
45
|
|
46 public static void Transfer(TraceContext from) {
|
|
47 _current = from == null ? new TraceContext() : new TraceContext(from);
|
|
48 }
|
|
49
|
|
50 public TraceContext ParentContext {
|
|
51 get {
|
|
52 return m_parent;
|
|
53 }
|
|
54 }
|
|
55
|
|
56 public LogicalOperation CurrentOperation {
|
|
57 get {
|
|
58 return m_currentOperation;
|
|
59 }
|
|
60 }
|
|
61
|
|
62 public LogicalOperation TraceBound {
|
|
63 get {
|
|
64 return m_traceBound;
|
|
65 }
|
|
66 }
|
|
67
|
|
68 public int ThreadId {
|
|
69 get {
|
|
70 return m_threadId;
|
|
71 }
|
|
72 }
|
|
73
|
|
74 public void StartLogicalOperation() {
|
|
75 StartLogicalOperation(null);
|
|
76 }
|
|
77
|
|
78 public void StartLogicalOperation(string name) {
|
|
79 LogEvent(TraceEventType.OperationStarted, "{0}", name);
|
|
80 m_currentOperation = new LogicalOperation(name, m_currentOperation);
|
|
81 }
|
|
82
|
|
83 public void EndLogicalOperation() {
|
|
84 if (m_traceBound == m_currentOperation) {
|
|
85 LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
|
|
86 } else {
|
|
87 var op = m_currentOperation;
|
|
88 m_currentOperation = m_currentOperation.Parent;
|
|
89 LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
|
|
90 }
|
|
91 }
|
|
92
|
|
93 void LogEvent(TraceEventType type, string format, params object[] args) {
|
37
|
94 LogChannel<TraceEvent>.Default.LogEvent(this, TraceEvent.Create(type, format, args));
|
36
|
95 }
|
|
96 }
|
|
97 }
|