##// END OF EJS Templates
Working on Implab.Diagnostics
cin -
r286:67ebcfd7d1c8 v3
parent child
Show More
@@ -0,0 +1,17
1 namespace Implab.Diagnostics
2 {
3 public abstract class TraceChannel {
4 readonly object m_id;
5
6 public object Id {
7 get {
8 return m_id;
9 }
10 }
11
12 protected TraceChannel(object id) {
13 m_id = id ?? new object();
14 }
15
16 }
17 } No newline at end of file
@@ -0,0 +1,83
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using Implab.Parallels;
5
6 namespace Implab.Diagnostics {
7 public class TraceRegistry {
8
9 class Subscription : IDisposable {
10 readonly WeakReference<TraceRegistry> m_registry;
11 readonly Action<object> m_unsubscribe;
12
13 public Subscription(TraceRegistry registry) {
14 m_registry = new WeakReference<TraceRegistry>(registry);
15 }
16
17 public void Dispose() {
18 TraceRegistry t;
19 if (m_registry.TryGetTarget(out t))
20 t.RemoveSubscription(this);
21 }
22 }
23
24 public static TraceRegistry Global { get; } = new TraceRegistry();
25
26 readonly object m_lock = new object();
27
28 readonly Dictionary<object, Action<TraceChannel>> m_subscriptions = new Dictionary<object, Action<TraceChannel>>();
29 readonly SimpleAsyncQueue<TraceChannel> m_channels = new SimpleAsyncQueue<TraceChannel>();
30
31 internal void Register(TraceChannel channel) {
32 // notifications can run in parallel
33 Action<TraceChannel>[] handlers = null;
34
35 lock(m_lock) {
36 m_channels.Enqueue(channel);
37 if (m_subscriptions.Count > 0) {
38 handlers = new Action<TraceChannel>[m_subscriptions.Count];
39 m_subscriptions.Values.CopyTo(handlers, 0);
40 }
41 }
42
43 if (handlers != null)
44 foreach(var h in handlers)
45 h(channel);
46 }
47
48 /// <summary>
49 /// Subscribes the specified handler to notifications about new trace
50 /// channels
51 /// </summary>
52 /// <param name="handler"></param>
53 /// <returns></returns>
54 public IDisposable Subscribe(Action<TraceChannel> handler, bool existing) {
55 Safe.ArgumentNotNull(handler, nameof(handler));
56
57 var cookie = new Subscription(this);
58
59 IEnumerable<TraceChannel> snap;
60
61 // lock to ensure that no new channels will be added
62 // while the subscription is added
63 lock(m_lock) {
64 m_subscriptions.Add(cookie, handler);
65 snap = m_channels.Snapshot();
66 }
67
68 // announce previously declared channels if required
69 if (existing) {
70 foreach(var c in snap)
71 handler(c);
72 }
73
74 // return the subscription
75 return cookie;
76 }
77
78 void RemoveSubscription(object cookie) {
79 lock(m_lock)
80 m_subscriptions.Remove(cookie);
81 }
82 }
83 } No newline at end of file
@@ -0,0 +1,27
1 using TraceSource = System.Diagnostics.TraceSource;
2
3 namespace Implab.Diagnostics {
4
5 /// <summary>
6 /// Trace channel which incapsulates <see cref="System.Diagnostics.TraceSource"/> instance.
7 /// </summary>
8 public class TraceSourceChannel : TraceChannel {
9 readonly TraceSource m_trace;
10
11 public TraceSourceChannel() : base(new object()) {
12 }
13
14 public TraceSourceChannel(object id) : base(id) {
15 }
16
17 public TraceSourceChannel(object id, string name) : base(id) {
18 m_trace = new TraceSource(name);
19 }
20
21 public TraceSource Source {
22 get {
23 return m_trace;
24 }
25 }
26 }
27 } No newline at end of file
@@ -0,0 +1,33
1 using System;
2 using System.Threading;
3 using TraceSource = System.Diagnostics.TraceSource;
4
5 namespace Implab.Diagnostics {
6 /// <summary>
7 /// This class is used to provide a single <see cref="TraceSourceChannel"/>
8 /// instance for the specified class in <typeparamref name="T"/> parameter.
9 /// </summary>
10 /// <typeparam name="T">
11 /// The class for which <see cref="TraceSourceChannel"/> is required.
12 /// </typeparam>
13 /// <remarks>
14 /// The <see cref="TraceSourceChannel"/> instance will be created on demand
15 /// and automatically registered in <see cref="TraceRegistry.Global"/>.
16 /// </remarks>
17 public static class TraceSourceChannel<T> {
18 static Lazy<TraceSourceChannel> _traceSource = new Lazy<TraceSourceChannel>(CreateChannel, LazyThreadSafetyMode.ExecutionAndPublication);
19
20 /// <summary>
21 /// The default <see cref="TraceSourceChannel"/> instance.
22 /// </summary>
23 public static TraceSourceChannel Default { get { return _traceSource.Value; } }
24
25 static TraceSourceChannel CreateChannel() {
26 var channel = new TraceSourceChannel(typeof(T), typeof(T).Name);
27
28 TraceRegistry.Global.Register(channel);
29
30 return channel;
31 }
32 }
33 } No newline at end of file
@@ -1,155 +1,38
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Diagnostics;
4 4 using System.Dynamic;
5 5 using System.Linq;
6 6 using Implab.Components;
7 7 using Implab.Diagnostics;
8 8 using Implab.ServiceHost.Unity;
9 9 using Implab.Xml;
10 10 using Unity;
11 11 using Unity.Injection;
12 12 using Unity.Registration;
13 13
14 14 namespace Implab.Playground {
15
16 public class Foo {
17
18 public class Bar {
19
20 }
21
22 public string Name { get; set; }
23
24 public int IntValue { get; set; }
25
26 public string StringValue { get; set; }
27
28 public void AddRange(Foo[] items) {
29 Console.WriteLine($"AddRange: Foo[]");
30 }
31
32 }
33
34 public class FooFactory : IFactory<Foo>, IFactory<Foo.Bar> {
35
36 public bool UseSsl { get; set; }
37
38 public string Connection { get; set; }
15 using static Trace<Bar>;
39 16
40 public Foo Create() {
41 return new Foo() {
42 Name = "AutoFac"
43 };
44 }
45
46 Foo.Bar IFactory<Foo.Bar>.Create() {
47 return new Foo.Bar();
48 }
49 }
50
51 public interface IContainer<T> {
52 T Instance { get; set; }
53 }
54
55 public class Container<T> : IContainer<T> {
56 public class Bar {
57
58 }
59
60 public class Bar<T2> {
61 public class Baz {
62
63 }
64
65 }
66
67 public Container() {
17 class Foo {
68 18
69 19 }
70 20
71 public Container(T instance) {
72 Instance = instance;
73 }
74
75 public T Instance { get; set; }
76
77 public void SetInstance(T value) {
78 Instance = value;
79 }
21 class Bar : Foo {
80 22
81 public void AddRange(List<T> items) {
82 Console.WriteLine($"AddRange: {typeof(List<T>)}");
83 23 }
84
85 public void AddRange(T[] items) {
86 Console.WriteLine($"AddRange: T[] ofType {typeof(T[])}");
87 }
88 }
89
90 24 public class Program {
91 25
92 26 static void Main(string[] args) {
93 var u1 = new Uri("/some/one");
94 27
95 dynamic obj = new ExpandoObject();
96
97 obj.Name = "Dynamo";
98
99 obj.Hello = new Func<string>(() => { return "Hello"; });
100
101 Console.WriteLine($"{obj.Hello()}");
102
103 }
104
105 static void Main2(string[] args) {
106 var listener = new SimpleTraceListener(Console.Out);
107 var source = Trace<TypeResolver>.TraceSource;
108 source.Switch.Level = SourceLevels.All;
109 source.Listeners.Add(listener);
110
111 var stopwatch = new Stopwatch();
112 stopwatch.Start();
113
114 var container = new UnityContainer();
115
116 Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
117 stopwatch.Restart();
118
119 container.LoadXmlConfiguration("data/sample.xml");
120
121 Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}");
122
123 stopwatch.Restart();
124 var instace1 = container.Resolve<IContainer<string>>();
125 Console.WriteLine($"Resolved1: {stopwatch.ElapsedMilliseconds}");
126
127 stopwatch.Restart();
128 var instace2 = container.Resolve<IContainer<Foo>>();
129 Console.WriteLine($"Resolved2: {stopwatch.ElapsedMilliseconds}");
130
131 DisplayContainerRegistrations(container);
132 }
133
134 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
135 string regName, regType, mapTo, lifetime;
136 Console.WriteLine("Container has {0} Registrations:",
137 theContainer.Registrations.Count());
138 foreach (ContainerRegistration item in theContainer.Registrations) {
139 regType = item.RegisteredType.FullName;
140 mapTo = item.MappedToType.FullName;
141 regName = item.Name ?? "[default]";
142 lifetime = item.LifetimeManager.LifetimeType.Name;
143 if (mapTo != regType) {
144 mapTo = " -> " + mapTo;
145 } else {
146 mapTo = string.Empty;
147 }
148 lifetime = lifetime.Substring(0, lifetime.Length - "LifetimeManager".Length);
149 Console.WriteLine("+ {0}{1} '{2}' {3}", regType, mapTo, regName, lifetime);
28 using(TraceRegistry.Global.Subscribe(ch => {
29 Console.WriteLine($"{ch.Id}: {ch.Source.Name}");
30 }, true)) {
31 Trace<Foo>.Log("Hi!");
32 Log("Respect!");
150 33 }
151 34 }
152 35
153 36
154 37 }
155 38 }
@@ -1,143 +1,145
1 1 using System;
2 2 using System.IO;
3 3 using System.Reflection;
4 4 using Implab.Diagnostics;
5 5 using Unity;
6 6
7 7 namespace Implab.ServiceHost.Unity {
8 using static Trace<ContainerBuilder>;
8 using Log = Trace<ContainerBuilder>;
9 9
10 10 public class ContainerBuilder {
11 11
12 12 readonly TypeResolver m_resolver;
13 13
14 14 readonly IUnityContainer m_container;
15 15
16 16 readonly ContainerConfigurationSchema m_schema;
17 17
18 18 Uri m_location;
19 19
20 20 public IUnityContainer Container {
21 21 get {
22 22 return m_container;
23 23 }
24 24 }
25 25
26 26 public ContainerBuilder() : this(null, null) {
27 27 }
28 28
29 29 public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) {
30 30 m_container = container ?? new UnityContainer();
31 31 m_resolver = new TypeResolver();
32 32 m_schema = schema ?? ContainerConfigurationSchema.Default;
33 33 }
34 34
35 35 public Type ResolveType(string typeReference) {
36 return string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true);
36 var resolved = string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true);
37 Log.Debug("ResolveType('{0}'): {1}", typeReference, resolved?.FullName);
38 return resolved;
37 39 }
38 40
39 41 public void Visit(ITypeRegistration registration) {
40 42 Safe.ArgumentNotNull(registration, nameof(registration));
41 43
42 44 var registrationType = registration.GetRegistrationType(this);
43 45 var implementationType = registration.GetImplementationType(this) ?? registrationType;
44 46
45 47 if (registrationType == null)
46 48 throw new Exception($"A type must be specified for the registration {registration.Name}");
47 49
48 50 var builder = new TypeRegistrationBuilder(
49 51 m_resolver,
50 52 registrationType,
51 53 implementationType
52 54 );
53 55
54 56 builder.Lifetime = registration.GetLifetime(this);
55 57
56 58 if (registration.MemberInjections != null) {
57 59 foreach(var member in registration.MemberInjections)
58 60 member.Visit(builder);
59 61 }
60 62
61 63 m_container.RegisterType(
62 64 builder.RegistrationType,
63 65 builder.ImplementationType,
64 66 registration.Name,
65 67 builder.Lifetime,
66 68 builder.Injections
67 69 );
68 70 }
69 71
70 72 public void Visit(IInstanceRegistration registration) {
71 73 Safe.ArgumentNotNull(registration, nameof(registration));
72 74
73 75 var registrationType = registration.GetRegistrationType(this);
74 76
75 77 var builder = new InstanceRegistrationBuilder (
76 78 m_resolver,
77 79 registrationType
78 80 );
79 81
80 82 builder.Lifetime = registration.GetLifetime(this);
81 83
82 84 if (registration.MemberInjections != null) {
83 85 foreach(var member in registration.MemberInjections)
84 86 member.Visit(builder.ValueBuilder);
85 87 }
86 88
87 89 if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null)
88 90 throw new Exception($"A type must be specified for the registration {registration.Name}");
89 91
90 92 m_container.RegisterInstance(
91 93 builder.RegistrationType ?? builder.ValueBuilder.ValueType,
92 94 registration.Name,
93 95 builder.ValueBuilder.Value,
94 96 builder.Lifetime
95 97 );
96 98 }
97 99
98 100 public void AddNamespace(string ns) {
99 101 m_resolver.AddNamespace(ns);
100 102 }
101 103
102 104 public void AddAssembly(string assembly) {
103 105
104 106 }
105 107
106 108 /// <summary>
107 109 /// Includes the confguration. Creates a new <see cref="ContainerBuilder"/>,
108 110 /// and loads the configuration to it. The created builder will share the
109 111 /// container and will have its own isolated type resolver.
110 112 /// </summary>
111 113 /// <param name="file">A path to configuration relative to the current configuration.</param>
112 114 public void Include(string file) {
113 115 var includeContext = new ContainerBuilder(m_container, m_schema);
114 116
115 117 if (m_location != null) {
116 118 var uri = new Uri(m_location, file);
117 119 includeContext.LoadConfig(uri);
118 120 } else {
119 121 includeContext.LoadConfig(file);
120 122 }
121 123 }
122 124
123 125 /// <summary>
124 126 /// Loads a configuration from the specified local file.
125 127 /// </summary>
126 128 /// <param name="file">The path to the configuration file.</param>
127 129 public void LoadConfig(string file) {
128 130 Safe.ArgumentNotEmpty(file, nameof(file));
129 131
130 132 LoadConfig(new Uri(Path.GetFullPath(file)));
131 133 }
132 134
133 135 public void LoadConfig(Uri location) {
134 136 Safe.ArgumentNotNull(location, nameof(location));
135 137
136 138 m_location = location;
137 139
138 140 var config = m_schema.LoadConfig(location.ToString());
139 141 config.Visit(this);
140 142 }
141 143
142 144 }
143 145 } No newline at end of file
@@ -1,17 +1,27
1 1 using System;
2 using System.Diagnostics;
2 using Stopwatch = System.Diagnostics.Stopwatch;
3 3
4 4 namespace Implab.Diagnostics {
5 5 public class LogicalOperation {
6 public Stopwatch OperationStopwatch { get; private set; }
6 readonly Stopwatch m_stopwatch;
7 7
8 8 public string Name { get; private set; }
9 9
10 10 internal LogicalOperation(string name) {
11 11 Name = string.IsNullOrEmpty(name) ? "<unnamed>" : name;
12 OperationStopwatch = Stopwatch.StartNew();
12 m_stopwatch = Stopwatch.StartNew();
13 }
14
15 public TimeSpan Elapsed {
16 get {
17 return m_stopwatch.Elapsed;
18 }
19 }
20
21 public void End() {
22 m_stopwatch.Stop();
13 23 }
14 24
15 25 public override string ToString() => Name;
16 26 }
17 27 } No newline at end of file
@@ -1,21 +1,21
1 1 using System;
2 2 using System.Diagnostics;
3 3
4 4 namespace Implab.Diagnostics {
5 5 public class LogicalOperationScope : IDisposable {
6 6 readonly TraceSource m_source;
7 7
8 8 readonly LogicalOperation m_operation;
9 9
10 10 internal LogicalOperationScope(TraceSource source, LogicalOperation operation) {
11 11 m_source = source;
12 12 m_operation = operation;
13 13 }
14 14
15 15 public void Dispose() {
16 m_operation.OperationStopwatch.Stop();
16 m_operation.End();
17 17 Trace.CorrelationManager.StopLogicalOperation();
18 18 m_source.TraceData(TraceEventType.Information, TraceEventCodes.StopLogicalOperation, m_operation);
19 19 }
20 20 }
21 21 } No newline at end of file
@@ -1,114 +1,114
1 1 using System;
2 2 using System.Diagnostics;
3 3 using System.IO;
4 4
5 5 namespace Implab.Diagnostics {
6 6 public class SimpleTraceListener : TextWriterTraceListener {
7 7 public SimpleTraceListener() {
8 8 }
9 9
10 10 public SimpleTraceListener(Stream stream) : base(stream) {
11 11 }
12 12
13 13 public SimpleTraceListener(TextWriter writer) : base(writer) {
14 14 }
15 15
16 16 public SimpleTraceListener(string fileName) : base(fileName) {
17 17 }
18 18
19 19 public SimpleTraceListener(Stream stream, string name) : base(stream, name) {
20 20 }
21 21
22 22 public SimpleTraceListener(TextWriter writer, string name) : base(writer, name) {
23 23 }
24 24
25 25 public SimpleTraceListener(string fileName, string name) : base(fileName, name) {
26 26 }
27 27
28 28 public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) {
29 29 switch (id) {
30 30 case TraceEventCodes.StartLogicalOperation:
31 31 TraceEvent(eventCache, source, eventType, id, "+{0}", data);
32 32 break;
33 33 case TraceEventCodes.StopLogicalOperation:
34 34 TraceEvent(eventCache, source, eventType, id, FormatStopLogicalOperation(data));
35 35 break;
36 36 default:
37 37 TraceEvent(eventCache, source, eventType, id, data?.ToString());
38 38 break;
39 39 }
40 40 }
41 41
42 42 string FormatStopLogicalOperation(object data) {
43 43 if (data is LogicalOperation op) {
44 return string.Format("-{0} ({1})", op, FormatTimespan(op.OperationStopwatch.Elapsed));
44 return string.Format("-{0} ({1})", op, FormatTimespan(op.Elapsed));
45 45 } else {
46 46 return data?.ToString();
47 47 }
48 48 }
49 49
50 50 string FormatTimespan(TimeSpan value) {
51 51 if (value.TotalSeconds < 10) {
52 52 return value.Milliseconds.ToString() + "ms";
53 53 } else if (value.TotalSeconds < 30) {
54 54 return string.Format("{0:0.###}s", value.TotalSeconds);
55 55 } else {
56 56 return value.ToString();
57 57 }
58 58 }
59 59
60 60 public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data) {
61 61 var prev = IndentLevel;
62 62 IndentLevel += eventCache.LogicalOperationStack.Count;
63 63 try {
64 64 base.TraceData(eventCache, source, eventType, id, data);
65 65 } finally {
66 66 IndentLevel = prev;
67 67 }
68 68 }
69 69
70 70 public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id) {
71 71 var prev = IndentLevel;
72 72 IndentLevel += eventCache.LogicalOperationStack.Count;
73 73 try {
74 74 base.TraceEvent(eventCache, source, eventType, id);
75 75 } finally {
76 76 IndentLevel = prev;
77 77 }
78 78 }
79 79
80 80 public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) {
81 81 TraceEvent(eventCache, source, eventType, id, String.Format(format, args));
82 82 }
83 83
84 84 public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) {
85 85 var prev = IndentLevel;
86 86 IndentLevel += eventCache.LogicalOperationStack.Count;
87 87 try {
88 88 LogicalOperation operation = null;
89 89 if (eventCache.LogicalOperationStack.Count > 0)
90 90 operation = eventCache.LogicalOperationStack.Peek() as LogicalOperation;
91 91
92 92 if (operation != null) {
93 base.TraceData(eventCache, source, eventType, id, FormatTimespan(operation.OperationStopwatch.Elapsed) + ": " + message);
93 base.TraceData(eventCache, source, eventType, id, FormatTimespan(operation.Elapsed) + ": " + message);
94 94 } else {
95 95 base.TraceData(eventCache, source, eventType, id, message);
96 96 }
97 97 } finally {
98 98 IndentLevel = prev;
99 99 }
100 100 }
101 101
102 102 public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId) {
103 103 var prev = IndentLevel;
104 104 IndentLevel += eventCache.LogicalOperationStack.Count;
105 105 try {
106 106 base.TraceTransfer(eventCache, source, id, message, relatedActivityId);
107 107 } finally {
108 108 IndentLevel = prev;
109 109 }
110 110 }
111 111
112 112
113 113 }
114 114 } No newline at end of file
@@ -1,160 +1,192
1 1 // enable System.Diagnostics trace methods
2 2 #define TRACE
3 3
4 4 using System;
5 5 using System.Collections.Generic;
6 6 using System.Diagnostics;
7 7 using System.Linq;
8 8 using System.Text;
9 9 using System.Threading;
10 10 using System.Threading.Tasks;
11 11
12 12 namespace Implab.Diagnostics {
13 /// <summary>
14 /// Static class which creates an individual <see cref="TraceSource"/> for
15 /// the type specified in the parameter <typeparamref name="T"/>.
16 /// </summary>
17 /// <typeparam name="T">The type for which tracing is demanded.</typeparam>
13 18 public static class Trace<T> {
14 19
15 static Lazy<TraceSource> _traceSource = new Lazy<TraceSource>(CreateChannel, LazyThreadSafetyMode.ExecutionAndPublication);
16
17 static int _nextId;
20 readonly static Lazy<TraceSource> _trace = new Lazy<TraceSource>(() => TraceSourceChannel<T>.Default.Source);
18 21
19 static TraceSource CreateChannel() {
20 var id = Interlocked.Increment(ref _nextId);
21 var trs = new TraceSource(typeof(T).Name);
22
23 TraceChannelRegistry.AllCannels.NotifyChannelCreated(new ChannelInfo(typeof(T), trs));
24
25 return trs;
26 }
27
28 public static TraceSource TraceSource { get { return _traceSource.Value; } }
22 public static TraceSource TraceSource { get { return _trace.Value; } }
29 23
30 24 #if NETFX_TRACE_BUG
31 25 readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>();
32 26 #endif
33 27
34 28 /// <summary>
35 /// Starts the logical operation nested to the current operation nested to the current one.
29 /// If this property is set then <see cref="Debug(string, object[])"/> will produce output.
30 /// </summary>
31 public static bool TraceVerbose {
32 get {
33 return TraceSource.Switch.ShouldTrace(TraceEventType.Verbose);
34 }
35 }
36
37 /// <summary>
38 /// If this property is set then <see cref="Log(string, object[])"/> will produce output.
36 39 /// </summary>
37 public static void StartLogicalOperation() {
38 Trace.CorrelationManager.StartLogicalOperation();
40 public static bool TraceInformation {
41 get {
42 return TraceSource.Switch.ShouldTrace(TraceEventType.Information);
43 }
44 }
39 45
46 /// <summary>
47 /// If this property is set then <see cref="Warn(string, object[])"/> will produce output.
48 /// </summary>
49 public static bool TraceWarnings {
50 get {
51 return TraceSource.Switch.ShouldTrace(TraceEventType.Warning);
40 52 }
53 }
54
55
41 56
42 57 /// <summary>
43 58 /// Starts the logical operation with the specified name, this name is usefull in logs.
44 59 /// </summary>
45 60 /// <param name="name">Name.</param>
46 61 #if NETFX_TRACE_BUG
47 62 public static void StartLogicalOperation(object name) {
48 63 m_currentOperation.Value = name;
49 64 Trace.CorrelationManager.StartLogicalOperation(name);
50 65 }
66
67 /// <summary>
68 /// Starts the logical operation nested to the current operation nested to the current one.
69 /// </summary>
70 public static void StartLogicalOperation() {
71 m_currentOperation.Value = new object();
72 Trace.CorrelationManager.StartLogicalOperation();
73
74 }
51 75 #else
52 76 public static void StartLogicalOperation(object name) {
53 77 Trace.CorrelationManager.StartLogicalOperation(name);
54 78 }
79
80 /// <summary>
81 /// Starts the logical operation nested to the current operation nested to the current one.
82 /// </summary>
83 public static void StartLogicalOperation() {
84 Trace.CorrelationManager.StartLogicalOperation();
85
86 }
55 87 #endif
56 88
57 89 /// <summary>
58 90 /// Ends the logical operation and restores the previous one.
59 91 /// </summary>
60 92 public static void StopLogicalOperation() {
61 93 Trace.CorrelationManager.StopLogicalOperation();
62 94 }
63 95
64 96 /// <summary>
65 97 /// Writes a debug message.
66 98 /// </summary>
67 99 /// <param name="format">Format.</param>
68 100 /// <param name="arguments">Arguments.</param>
69 101 [Conditional("DEBUG")]
70 102 public static void Debug(string format, params object[] arguments) {
71
103 TraceSource.TraceEvent(TraceEventType.Verbose, 0, format, arguments);
72 104 }
73 105
74 106 /// <summary>
75 107 /// Writes an informational message.
76 108 /// </summary>
77 109 /// <param name="format">Format.</param>
78 110 /// <param name="arguments">Arguments.</param>
79 111 [Conditional("TRACE")]
80 112 public static void Log(string format, params object[] arguments) {
81 113 TraceSource.TraceEvent(TraceEventType.Information, 0, format, arguments);
82 114 }
83 115
84 116 /// <summary>
85 117 /// Writes a warning message.
86 118 /// </summary>
87 119 /// <param name="format">Format.</param>
88 120 /// <param name="arguments">Arguments.</param>
89 121 public static void Warn(string format, params object[] arguments) {
90 122 TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments);
91 123 }
92 124
93 125 /// <summary>
94 126 /// Writes a error message.
95 127 /// </summary>
96 128 /// <param name="format">Format.</param>
97 129 /// <param name="arguments">Arguments.</param>
98 130 public static void Error(string format, params object[] arguments) {
99 131 TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments);
100 132 }
101 133
102 134 public static void Error(Exception err) {
103 135 TraceSource.TraceData(TraceEventType.Error, 0, err);
104 136 }
105 137
106 138 /// <summary>
107 139 /// This method save the current activity, and transfers to the specified activity,
108 140 /// emits <see cref="TraceEventType.Start"/> and returns a scope of the new
109 141 /// activity.
110 142 /// </summary>
111 143 /// <param name="activityName">The name of the new activity/</param>
112 144 /// <param name="activityId">The identifier of the activity to which
113 145 /// the control will be transferred</param>
114 146 /// <returns>A scope of the new activity, dispose it to transfer
115 147 /// the control back to the original activity.</returns>
116 148 public static ActivityScope TransferActivity(string activityName, Guid activityId) {
117 149 var prev = Trace.CorrelationManager.ActivityId;
118 150
119 151 TraceSource.TraceTransfer(0, "Transfer", activityId);
120 152 Trace.CorrelationManager.ActivityId = activityId;
121 153 TraceSource.TraceEvent(TraceEventType.Start, 0, activityName);
122 154
123 155 return new ActivityScope(TraceSource, prev, 0, activityName);
124 156 }
125 157
126 158 /// <summary>
127 159 /// Emits <see cref="TraceEventType.Start"/> and returns a scope of the
128 160 /// activity.
129 161 /// </summary>
130 162 /// <param name="activityName">The name of the activity to start</param>
131 163 /// <returns>A scope of the new activity, dispose it to emit
132 164 /// <see cref="TraceEventType.Stop"/> for the current activity.</returns>
133 165 public static ActivityScope StartActivity(string activityName) {
134 166 if (Trace.CorrelationManager.ActivityId == Guid.Empty)
135 167 Trace.CorrelationManager.ActivityId = Guid.NewGuid();
136 168
137 169 var prev = Trace.CorrelationManager.ActivityId;
138 170
139 171 TraceSource.TraceEvent(TraceEventType.Start, 0, activityName);
140 172 return new ActivityScope(TraceSource, prev, 0, activityName);
141 173 }
142 174
143 175 /// <summary>
144 176 /// Creates new <see cref="LogicalOperation(string)"/> and calls
145 177 /// to <see cref="CorrelationManager.StartLogicalOperation(object)"/>
146 178 /// passing the created operation as identity. Calls
147 179 /// <see cref="TraceSource.TraceData(TraceEventType, int, object)"/>
148 180 /// to notify listeners on operation start.
149 181 /// </summary>
150 182 /// <param name="name">The name of the logical operation.</param>
151 183 /// <returns>Logical operation scope, disposing it will stop
152 184 /// logical operation and notify trace listeners.</returns>
153 185 public static LogicalOperationScope LogicalOperation(string name) {
154 186 var operation = new LogicalOperation(name);
155 187 TraceSource.TraceData(TraceEventType.Information, TraceEventCodes.StartLogicalOperation, operation);
156 188 StartLogicalOperation(operation);
157 189 return new LogicalOperationScope(TraceSource, operation);
158 190 }
159 191 }
160 192 }
@@ -1,10 +1,11
1 1 using System;
2 2
3 3 namespace Implab.Diagnostics {
4 4 /// <summary>
5 5 /// Used to mark class which uses <see cref="Trace{T}"/> class to trace it's events
6 6 /// </summary>
7 7 [AttributeUsage(AttributeTargets.Class)]
8 [Obsolete("Use TraceRegistry to monitor trace sources")]
8 9 public class TraceSourceAttribute : Attribute {
9 10 }
10 11 }
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