##// END OF EJS Templates
improved trace system
cin -
r52:edf0bc558596 default
parent child
Show More
@@ -1,211 +1,238
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4 using System.Text;
5 5 using System.Threading;
6 6 using System.Threading.Tasks;
7 7
8 8 namespace Implab.Diagnostics {
9 9 /// <summary>
10 10 /// ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки, привязываСтся ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΈ содСрТит Π² сСбС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ стСкС логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.
11 11 /// </summary>
12 12 /// <remarks>
13 13 /// ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки пСрСдаСтся ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΡΠΌ событий для опрСдСлСния мСста, Π³Π΄Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΎ событиС.
14 14 /// </remarks>
15 15 public class TraceContext {
16 16 LogicalOperation m_currentOperation;
17 17 readonly LogicalOperation m_bound;
18 18 readonly int m_threadId;
19 19
20 20 [ThreadStatic]
21 21 static TraceContext _current;
22 22
23 23 /// <summary>
24 24 /// Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ контСкст трассировки для ΠΏΠΎΡ‚ΠΎΠΊΠ°, создаСтся астоматичСски ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ.
25 25 /// </summary>
26 26 public static TraceContext Current {
27 27 get {
28 28 if (_current == null) {
29 29 _current = new TraceContext();
30 30 _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId);
31 31 }
32 32 return _current;
33 33 }
34 34 }
35 35
36 36 TraceContext(TraceContext context)
37 37 : this(context, false) {
38 38 }
39 39
40 40 TraceContext(TraceContext context, bool attach) {
41 41 if (context == null)
42 42 throw new ArgumentNullException("context");
43 43
44 44 m_currentOperation = context.CurrentOperation;
45 45 m_bound = attach ? context.BoundOperation : context.CurrentOperation;
46 46 m_threadId = Thread.CurrentThread.ManagedThreadId;
47 47 }
48 48
49 49 TraceContext() {
50 50 m_currentOperation = new LogicalOperation();
51 51 m_bound = m_currentOperation;
52 52 m_threadId = Thread.CurrentThread.ManagedThreadId;
53 53 }
54 54
55 55 /// <summary>
56 56 /// ΠŸΡ€ΠΈ нСобходимости ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ состояниС контСкста трассивровки Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.
57 57 /// </summary>
58 58 /// <param name="from">Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ контСкст трассировки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пСрСдаСтся.</param>
59 59 /// <remarks>
60 60 /// <para>
61 61 /// ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ происходит Π·Π° счСт создания Π½ΠΎΠ²ΠΎΠ³ΠΎ контСкста трассировки ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π΅Π³ΠΎ
62 62 /// состояния ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ контСкста. ΠŸΡ€ΠΈ этом копируСтся стСк ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π² Π½ΠΎΠ²ΠΎΠΌ
63 63 /// контСкстС Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Ρ‹.
64 64 /// </para>
65 65 /// <para>
66 66 /// Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° состояния ΡΠΎΡΡ‚ΠΎΡΠ»Π°ΡΡŒ, Ρ‚ΠΎ вызываСтся событиС трассировки <see cref="TraceEventType.Fork"/>.
67 67 /// </para>
68 68 /// </remarks>
69 69 public static void Fork(TraceContext from) {
70 70 if (_current == from)
71 71 return;
72 72 if (from != null) {
73 73 var context = new TraceContext(from);
74 74 context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId);
75 75 _current = context;
76 76 } else {
77 77 _current = new TraceContext();
78 78 }
79 79 }
80 80
81 81 /// <summary>
82 82 /// Π—Π°Π΄Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ контСкст, Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅
83 83 /// логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС.
84 84 /// </summary>
85 85 /// <param name="source"></param>
86 86 public static void Attach(TraceContext source) {
87 87 if (_current == source)
88 88 return;
89 89 if (source != null) {
90 90 var context = new TraceContext(source, true);
91 91 context.LogEvent(TraceEventType.Attach, "[{0}]-->[{1}]", source.ThreadId, context.ThreadId);
92 92 _current = context;
93 93 } else {
94 94 _current = new TraceContext();
95 95 }
96 96 }
97 97
98 98 /// <summary>
99 99 /// ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ контСкст трассировки ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠ°, для дальнСйшСй Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ
100 100 /// <see cref="Attach(TraceContext)"/>.
101 101 /// </summary>
102 102 /// <returns>ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки ΠΏΠΎΡ‚ΠΎΠΊΠ°</returns>
103 103 /// <remarks>
104 104 /// ПослС отсоСдинСния контСкста трассировки ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ трассировкС Π² этом
105 105 /// ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ создан Π½ΠΎΠ²Ρ‹ΠΉ контСкст.
106 106 /// </remarks>
107 107 public static TraceContext Detach() {
108 108 var context = Current;
109 109 context.LogEvent(TraceEventType.Detach, null);
110 110 _current = null;
111 111 return context;
112 112 }
113 113
114 114 /// <summary>
115 115 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ копию Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста, Π΄Π°Π½Π½ΡƒΡŽ копию ΠΌΠΎΠΆΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ‡Π΅Ρ€Π΅Π· <see cref="Fork(TraceContext)"/>
116 116 /// </summary>
117 117 /// <returns>Копия Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста трассировки.</returns>
118 118 public static TraceContext Snapshot() {
119 return _current == null ? new TraceContext() : new TraceContext(_current);
119 return _current == null ? new TraceContext() : new TraceContext(_current,false);
120 120 }
121 121
122 122 /// <summary>
123 123 /// ВыполняСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ΅ дСйствиС Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС трассировки, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ восстанавливаСт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ контСкст трассировки ΠΏΠΎΡ‚ΠΎΠΊΠ°.
124 124 /// </summary>
125 125 /// <param name="action"></param>
126 126 public void Invoke(Action action) {
127 127 if (action == null)
128 128 throw new ArgumentNullException("action");
129 129 var old = _current;
130 130 Fork(this);
131 131 try {
132 132 action();
133 133 } finally {
134 if(_current != null)
134 135 _current.EndAllOperations();
135 136 _current = old;
136 137 }
137 138 }
138 139
139 140 /// <summary>
140 141 /// ВСкущая логичСская опСрация.
141 142 /// </summary>
142 143 public LogicalOperation CurrentOperation {
143 144 get {
144 145 return m_currentOperation;
145 146 }
146 147 }
147 148
148 149 /// <summary>
149 150 /// ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π½ΠΈΠΆΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ нСльзя ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ Π² стСкС логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Ρ‚.Π΅. ΠΎΠ½Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС.
150 151 /// </summary>
151 152 public LogicalOperation BoundOperation {
152 153 get {
153 154 return m_bound;
154 155 }
155 156 }
156 157
157 158 /// <summary>
158 159 /// ΠŸΠΎΡ‚ΠΎΠΊ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ создан контСкст трассировки.
159 160 /// </summary>
160 161 public int ThreadId {
161 162 get {
162 163 return m_threadId;
163 164 }
164 165 }
165 166
166 167 /// <summary>
167 168 /// НачинаСт Π±Π΅Π·Ρ‹ΠΌΡΠ½Π½ΡƒΡŽ Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ.
168 169 /// </summary>
169 170 public void StartLogicalOperation() {
170 171 StartLogicalOperation(null);
171 172 }
172 173
173 174 /// <summary>
174 175 /// НачинаСт Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. Бозданная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π²Π°Π»Π΅Π½Π° Π² стСк логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ контСкста, Π·Π°Ρ‚Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ создано ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰Π΅Π΅ событиС.
175 176 /// </summary>
176 177 /// <param name="name">Имя Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
177 178 public void StartLogicalOperation(string name) {
178 179 m_currentOperation = new LogicalOperation(name, m_currentOperation);
179 180 LogEvent(TraceEventType.OperationStarted, name);
180 181 }
181 182
182 183 /// <summary>
183 184 /// Π—Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π½Π°Ρ‡Π°Ρ‚ΡƒΡŽ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… контСкстах Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Ρ‹ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС.
184 185 /// </summary>
185 186 /// <remarks>
186 187 /// ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° создаСтся событиС ΠΆΡƒΡ€Π½Π°Π»Π° трассировки, Π»ΠΈΠ±ΠΎ ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π»ΠΈΠ±ΠΎ ΠΎΠ± ошибки, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ данная опСрация
187 188 /// Π½Π°Ρ‡Π°Ρ‚Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ контСкстС.
188 189 /// </remarks>
189 190 public void EndLogicalOperation() {
190 191 if (m_bound == m_currentOperation) {
191 192 LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
192 193 } else {
193 194 var op = m_currentOperation;
194 195 LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
195 196 m_currentOperation = m_currentOperation.Parent;
196 197 }
197 198 }
198 199
199 200 /// <summary>
201 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ копию контСкста ΠΈ возвращаСтся Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС, это позволяСт Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅, Π° Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ - Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ.
202 /// </summary>
203 /// <returns>ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ.</returns>
204 public TraceContext DetachLogicalOperation() {
205 if (m_bound == m_currentOperation) {
206 return new TraceContext();
207 } else {
208 var detached = new TraceContext(this, true);
209 m_currentOperation = m_currentOperation.Parent;
210 return detached;
211 }
212 }
213
214 public void BindLogicalOperationToPromise(IPromiseBase promise) {
215 Safe.ArgumentNotNull(promise, "promise");
216
217 var ctx = DetachLogicalOperation();
218 promise.Finally(() => {
219 var old = _current;
220 TraceContext.Attach(ctx);
221 TraceContext.Current.EndLogicalOperation();
222 _current = old;
223 });
224 }
225
226 /// <summary>
200 227 /// Π—Π°Π²Ρ€Π΅ΡˆΠ°Π΅Ρ‚ всС Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ Π² этом контСкстС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ
201 228 /// </summary>
202 229 public void EndAllOperations() {
203 230 while (m_bound != m_currentOperation)
204 231 EndLogicalOperation();
205 232 }
206 233
207 234 void LogEvent(TraceEventType type, string format, params object[] args) {
208 235 LogChannel<TraceEvent>.Default.LogEvent(this, TraceEvent.Create(type, format, args));
209 236 }
210 237 }
211 238 }
@@ -1,31 +1,34
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4 using System.Text;
5 5
6 6 namespace Implab.Diagnostics {
7 7 public class TraceEvent {
8 8 public string Message {
9 9 get;
10 10 private set;
11 11 }
12 12
13 13 public TraceEventType EventType {
14 14 get;
15 15 private set;
16 16 }
17 17
18 18 public TraceEvent(TraceEventType type, string message) {
19 19 EventType = type;
20 20 Message = message;
21 21 }
22 22
23 23 public override string ToString() {
24 if (EventType == TraceEventType.Information)
25 return Message;
26 else
24 27 return String.Format("{0}: {1}", EventType, Message);
25 28 }
26 29
27 30 public static TraceEvent Create(TraceEventType type, string format, params object[] args) {
28 31 return new TraceEvent(type, format == null ? String.Empty : String.Format(format, args));
29 32 }
30 33 }
31 34 }
@@ -1,50 +1,55
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Diagnostics;
4 4 using System.Linq;
5 5 using System.Text;
6 6 using System.Threading.Tasks;
7 7
8 8 namespace Implab.Diagnostics {
9 9 /// <summary>
10 10 /// Класс для ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ событий выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, события ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· <see cref="LogChannel{TraceEvent}"/>.
11 11 /// Π–ΡƒΡ€Π½Π°Π» трассировки ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ логичСский Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ сущСствуСт всСгда, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ тСсно связан с
12 12 /// контСкстом трассировки.
13 13 /// </summary>
14 14 public static class TraceLog {
15 15 [Conditional("TRACE")]
16 16 public static void StartLogicalOperation() {
17 17 TraceContext.Current.StartLogicalOperation();
18 18 }
19 19
20 20 [Conditional("TRACE")]
21 21 public static void StartLogicalOperation(string name) {
22 22 TraceContext.Current.StartLogicalOperation(name);
23 23 }
24 24
25 25 [Conditional("TRACE")]
26 26 public static void EndLogicalOperation() {
27 27 TraceContext.Current.EndLogicalOperation();
28 28 }
29 29
30 30 [Conditional("TRACE")]
31 public static void BindLogicalOperationToPromise(IPromiseBase promise) {
32 TraceContext.Current.BindLogicalOperationToPromise(promise);
33 }
34
35 [Conditional("TRACE")]
31 36 public static void TraceInformation(string format, params object[] arguments) {
32 37 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Information, format, arguments));
33 38 }
34 39
35 40 [Conditional("TRACE")]
36 41 public static void TraceWarning(string format, params object[] arguments) {
37 42 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Warning, format, arguments));
38 43 }
39 44
40 45 [Conditional("TRACE")]
41 46 public static void TraceError(string format, params object[] arguments) {
42 47 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Error, format, arguments));
43 48 }
44 49
45 50 [Conditional("TRACE")]
46 51 public static void TraceError(Exception err) {
47 52 TraceError("{0}", err);
48 53 }
49 54 }
50 55 }
General Comments 0
You need to be logged in to leave comments. Login now