##// END OF EJS Templates
minor changes
cin -
r195:ea485487a424 v2
parent child
Show More
@@ -1,65 +1,65
1 namespace Implab.Diagnostics {
1 namespace Implab.Diagnostics {
2 struct OperationContext {
2 struct OperationContext {
3 public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false);
3 public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false);
4
4
5 LogicalOperation m_initial;
5 LogicalOperation m_initial;
6 LogicalOperation m_current;
6 LogicalOperation m_current;
7 bool m_ownership;
7 bool m_ownership;
8
8
9 public OperationContext(LogicalOperation operation, bool ownership) {
9 public OperationContext(LogicalOperation operation, bool ownership) {
10 Safe.ArgumentNotNull(operation, "operation");
10 Safe.ArgumentNotNull(operation, "operation");
11
11
12 m_initial = operation;
12 m_initial = operation;
13 m_current = operation;
13 m_current = operation;
14 m_ownership = ownership;
14 m_ownership = ownership;
15 }
15 }
16
16
17 public LogicalOperation CurrentOperation {
17 public LogicalOperation CurrentOperation {
18 get { return m_current; }
18 get { return m_current; }
19 }
19 }
20
20
21 public void BeginLogicalOperation(string name) {
21 public void BeginLogicalOperation(string name) {
22 m_current = new LogicalOperation(name, m_current);
22 m_current = new LogicalOperation(name, m_current);
23 }
23 }
24
24
25 public LogicalOperation DetachLogicalOperation() {
25 public LogicalOperation DetachLogicalOperation() {
26 var detached = m_current;
26 var detached = m_current;
27 if (m_current != LogicalOperation.EMPTY) {
27 if (m_current != LogicalOperation.EMPTY) {
28 if (m_current != m_initial)
28 if (m_current != m_initial)
29 m_current = m_current.Parent;
29 m_current = m_current.Parent;
30 else if (m_ownership)
30 else if (m_ownership)
31 m_current = LogicalOperation.EMPTY;
31 m_current = LogicalOperation.EMPTY;
32 else {
32 else {
33 TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context");
33 TraceLog.TraceWarning("DetachLogicalOperation can't be performed in the current context");
34 detached = LogicalOperation.EMPTY;
34 detached = LogicalOperation.EMPTY;
35 }
35 }
36 } else {
36 } else {
37 TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context");
37 TraceLog.TraceWarning("DetachLogicalOperation can't be performed in the current context");
38 }
38 }
39
39
40 return detached;
40 return detached;
41 }
41 }
42
42
43 public LogicalOperation EndLogicalOperation() {
43 public LogicalOperation EndLogicalOperation() {
44 var current = m_current;
44 var current = m_current;
45 if (m_current != LogicalOperation.EMPTY && (m_current != m_initial || m_ownership)) {
45 if (m_current != LogicalOperation.EMPTY && (m_current != m_initial || m_ownership)) {
46 m_current = m_current.Parent;
46 m_current = m_current.Parent;
47 if (current == m_initial) {
47 if (current == m_initial) {
48 // we have complete the owned operation
48 // we have complete the owned operation
49 m_initial = m_current;
49 m_initial = m_current;
50 m_ownership = false;
50 m_ownership = false;
51 }
51 }
52 } else {
52 } else {
53 TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context");
53 TraceLog.TraceWarning("EndLogicalOperation can't be performed in the current context");
54 }
54 }
55 return current;
55 return current;
56 }
56 }
57
57
58 public void Leave() {
58 public void Leave() {
59
59
60 if ((m_ownership && m_current != LogicalOperation.EMPTY) || (!m_ownership && m_current != m_initial) )
60 if ((m_ownership && m_current != LogicalOperation.EMPTY) || (!m_ownership && m_current != m_initial) )
61 TraceLog.TraceWarning("Trying to leave unfinished logical operation {0}", m_current.Name);
61 TraceLog.TraceWarning("Trying to leave unfinished logical operation {0}", m_current.Name);
62 }
62 }
63 }
63 }
64 }
64 }
65
65
@@ -1,83 +1,82
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Threading;
3 using System.Threading;
4
4
5 namespace Implab.Diagnostics {
5 namespace Implab.Diagnostics {
6 /// <summary>
6 /// <summary>
7 /// Trace context is bound to the specific thread, each thread has it's own ThreadContext.
7 /// Trace context is bound to the specific thread, each thread has it's own ThreadContext.
8 /// </summary>
8 /// </summary>
9 /// <remarks>
9 /// <remarks>
10 /// ThreadContext manages relations between logical operations and threads.
10 /// ThreadContext manages relations between logical operations and threads.
11 /// </remarks>
11 /// </remarks>
12 public class TraceContext {
12 public class TraceContext {
13
13
14 [ThreadStatic]
14 [ThreadStatic]
15 static TraceContext _instance;
15 static TraceContext _instance;
16
16
17 OperationContext m_current = OperationContext.EMPTY;
17 OperationContext m_current = OperationContext.EMPTY;
18 readonly Stack<OperationContext> m_stack = new Stack<OperationContext>();
18 readonly Stack<OperationContext> m_stack = new Stack<OperationContext>();
19 readonly int m_threadId;
19 readonly int m_threadId;
20
20
21 public static TraceContext Instance {
21 public static TraceContext Instance {
22 get {
22 get {
23 if (_instance == null)
23 if (_instance == null)
24 _instance = new TraceContext();
24 _instance = new TraceContext();
25 return _instance;
25 return _instance;
26 }
26 }
27 }
27 }
28
28
29 public TraceContext() {
29 public TraceContext() {
30 m_threadId = Thread.CurrentThread.ManagedThreadId;
30 m_threadId = Thread.CurrentThread.ManagedThreadId;
31 }
31 }
32
32
33 public int ThreadId {
33 public int ThreadId {
34 get { return m_threadId; }
34 get { return m_threadId; }
35 }
35 }
36
36
37 public LogicalOperation CurrentOperation {
37 public LogicalOperation CurrentOperation {
38 get {
38 get {
39 return m_current.CurrentOperation;
39 return m_current.CurrentOperation;
40 }
40 }
41 }
41 }
42
42
43 public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) {
43 public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) {
44 //var prev = CurrentOperation;
44 //var prev = CurrentOperation;
45 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(takeOwnership ? TraceEventType.Attach : TraceEventType.Enter, String.Format("{0} -> {1}",prev.Name, operation.Name)));
45 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(takeOwnership ? TraceEventType.Attach : TraceEventType.Enter, String.Format("{0} -> {1}",prev.Name, operation.Name)));
46 m_stack.Push(m_current);
46 m_stack.Push(m_current);
47 m_current = new OperationContext(operation, takeOwnership);
47 m_current = new OperationContext(operation, takeOwnership);
48 }
48 }
49
49
50 public void StartLogicalOperation(string name) {
50 public void StartLogicalOperation(string name) {
51 LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationStarted, name));
51 LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationStarted, name));
52 m_current.BeginLogicalOperation(name);
52 m_current.BeginLogicalOperation(name);
53 }
53 }
54
54
55 public void StartLogicalOperation() {
55 public void StartLogicalOperation() {
56 StartLogicalOperation(String.Empty);
56 StartLogicalOperation(String.Empty);
57 }
57 }
58
58
59 public void EndLogicalOperation() {
59 public LogicalOperation EndLogicalOperation() {
60 var op = m_current.EndLogicalOperation();
60 return m_current.EndLogicalOperation();
61 LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",op.Name, op.Duration)));
62 }
61 }
63
62
64 public LogicalOperation DetachLogicalOperation() {
63 public LogicalOperation DetachLogicalOperation() {
65 var prev = m_current.DetachLogicalOperation();
64 var prev = m_current.DetachLogicalOperation();
66 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Detach, String.Format("{0} -> {1}",prev.Name, CurrentOperation.Name)));
65 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Detach, String.Format("{0} -> {1}",prev.Name, CurrentOperation.Name)));
67 return prev;
66 return prev;
68 }
67 }
69
68
70 public void Leave() {
69 public void Leave() {
71 if (m_stack.Count > 0) {
70 if (m_stack.Count > 0) {
72 m_current.Leave();
71 m_current.Leave();
73 //var prev = CurrentOperation;
72 //var prev = CurrentOperation;
74 m_current = m_stack.Pop();
73 m_current = m_stack.Pop();
75 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Leave, String.Format("{0} -> {1}", prev.Name, CurrentOperation.Name)));
74 //LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Leave, String.Format("{0} -> {1}", prev.Name, CurrentOperation.Name)));
76 } else {
75 } else {
77 TraceLog.TraceWarning("Attempt to leave the last operation context");
76 TraceLog.TraceWarning("Attempt to leave the last operation context");
78 m_current = OperationContext.EMPTY;
77 m_current = OperationContext.EMPTY;
79 }
78 }
80 }
79 }
81 }
80 }
82 }
81 }
83
82
@@ -1,29 +1,47
1 using System;
1 using System;
2
2
3 namespace Implab.Diagnostics {
3 namespace Implab.Diagnostics {
4 public class TraceEvent {
4 public class TraceEvent {
5 public string Message {
5 public string Message {
6 get;
6 get;
7 private set;
7 private set;
8 }
8 }
9
9
10 public TraceEventType EventType {
10 public TraceEventType EventType {
11 get;
11 get;
12 private set;
12 private set;
13 }
13 }
14
14
15 public TraceEvent(TraceEventType type, string message) {
15 /// <summary>
16 /// The logical operation this event belongs to.
17 /// </summary>
18 public LogicalOperation Operation {
19 get;
20 private set;
21 }
22
23 /// <summary>
24 /// Gets the time offset in milliseconds from the start of the operation, if the operation is not specified the value is zero.
25 /// </summary>
26 public int OperationTime {
27 get;
28 private set;
29 }
30
31 public TraceEvent(LogicalOperation operation, TraceEventType type, string message) {
16 EventType = type;
32 EventType = type;
17 Message = message;
33 Message = message;
34 Operation = operation;
35 if (operation != null)
36 OperationTime = operation.Duration;
18 }
37 }
19
38
20 public override string ToString() {
39 public override string ToString() {
21 /*return EventType == TraceEventType.Information ? Message : String.Format("{0}: {1}", EventType, Message);*/
22 return Message;
40 return Message;
23 }
41 }
24
42
25 public static TraceEvent Create(TraceEventType type, string format, params object[] args) {
43 public static TraceEvent Create(LogicalOperation operation, TraceEventType type, string format, params object[] args) {
26 return new TraceEvent(type, format == null ? String.Empty : String.Format(format, args));
44 return new TraceEvent(operation, type, format == null ? String.Empty : String.Format(format, args));
27 }
45 }
28 }
46 }
29 }
47 }
@@ -1,50 +1,70
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Diagnostics;
3 using System.Diagnostics;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6 using System.Threading.Tasks;
6 using System.Threading.Tasks;
7
7
8 namespace Implab.Diagnostics {
8 namespace Implab.Diagnostics {
9 /// <summary>
9 /// <summary>
10 /// Класс для ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ событий выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, события ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· <see cref="LogChannel{TraceEvent}"/>.
10 /// This class is used to trace a logical flow of the application, it publishes events to the default <see cref="TraceEvent"/> channel.
11 /// Π–ΡƒΡ€Π½Π°Π» трассировки ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ логичСский Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ сущСствуСт всСгда, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ тСсно связан с
12 /// контСкстом трассировки.
13 /// </summary>
11 /// </summary>
14 public static class TraceLog {
12 public static class TraceLog {
13 /// <summary>
14 /// Starts the logical operation nested to the current operation nested to the current one.
15 /// </summary>
15 [Conditional("TRACE")]
16 [Conditional("TRACE")]
16 public static void StartLogicalOperation() {
17 public static void StartLogicalOperation() {
17 TraceContext.Instance.StartLogicalOperation();
18 TraceContext.Instance.StartLogicalOperation();
19
18 }
20 }
19
21
22 /// <summary>
23 /// Starts the logical operation with the specified name, this name is usefull in logs.
24 /// </summary>
25 /// <param name="name">Name.</param>
20 [Conditional("TRACE")]
26 [Conditional("TRACE")]
21 public static void StartLogicalOperation(string name) {
27 public static void StartLogicalOperation(string name) {
22 TraceContext.Instance.StartLogicalOperation(name);
28 TraceContext.Instance.StartLogicalOperation(name);
23 }
29 }
24
30
31 /// <summary>
32 /// Ends the logical operation and restores the previous one.
33 /// </summary>
25 [Conditional("TRACE")]
34 [Conditional("TRACE")]
26 public static void EndLogicalOperation() {
35 public static void EndLogicalOperation() {
27 TraceContext.Instance.EndLogicalOperation();
36 var op = TraceContext.Instance.EndLogicalOperation();
37 LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",op.Name, op.Duration)));
28 }
38 }
29
39
40 /// <summary>
41 /// Writes an informational message.
42 /// </summary>
43 /// <param name="format">Format.</param>
44 /// <param name="arguments">Arguments.</param>
30 [Conditional("TRACE")]
45 [Conditional("TRACE")]
31 public static void TraceInformation(string format, params object[] arguments) {
46 public static void TraceInformation(string format, params object[] arguments) {
32 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Information, format, arguments));
47 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Information, format, arguments));
33 }
48 }
34
49
50 /// <summary>
51 /// Writes a warning message.
52 /// </summary>
53 /// <param name="format">Format.</param>
54 /// <param name="arguments">Arguments.</param>
35 [Conditional("TRACE")]
55 [Conditional("TRACE")]
36 public static void TraceWarning(string format, params object[] arguments) {
56 public static void TraceWarning(string format, params object[] arguments) {
37 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Warning, format, arguments));
57 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Warning, format, arguments));
38 }
58 }
39
59
40 [Conditional("TRACE")]
60 [Conditional("TRACE")]
41 public static void TraceError(string format, params object[] arguments) {
61 public static void TraceError(string format, params object[] arguments) {
42 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Error, format, arguments));
62 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Error, format, arguments));
43 }
63 }
44
64
45 [Conditional("TRACE")]
65 [Conditional("TRACE")]
46 public static void TraceError(Exception err) {
66 public static void TraceError(Exception err) {
47 TraceError("{0}", err);
67 TraceError("{0}", err);
48 }
68 }
49 }
69 }
50 }
70 }
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now