Auto status change to "Under Review"
| @@ -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 | 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.Dynamic; |
|
4 | using System.Dynamic; | |
| 5 | using System.Linq; |
|
5 | using System.Linq; | |
| 6 | using Implab.Components; |
|
6 | using Implab.Components; | |
| 7 | using Implab.Diagnostics; |
|
7 | using Implab.Diagnostics; | |
| 8 | using Implab.ServiceHost.Unity; |
|
8 | using Implab.ServiceHost.Unity; | |
| 9 | using Implab.Xml; |
|
9 | using Implab.Xml; | |
| 10 | using Unity; |
|
10 | using Unity; | |
| 11 | using Unity.Injection; |
|
11 | using Unity.Injection; | |
| 12 | using Unity.Registration; |
|
12 | using Unity.Registration; | |
| 13 |
|
13 | |||
| 14 | namespace Implab.Playground { |
|
14 | namespace Implab.Playground { | |
| 15 |
|
15 | using static Trace<Bar>; | ||
| 16 | public class Foo { |
|
16 | ||
| 17 |
|
17 | class Foo { | ||
| 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 |
|
18 | |||
| 32 | } |
|
19 | } | |
| 33 |
|
20 | |||
| 34 | public class FooFactory : IFactory<Foo>, IFactory<Foo.Bar> { |
|
21 | class Bar : Foo { | |
| 35 |
|
||||
| 36 | public bool UseSsl { get; set; } |
|
|||
| 37 |
|
||||
| 38 | public string Connection { get; set; } |
|
|||
| 39 |
|
||||
| 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 |
|
22 | |||
| 60 | public class Bar<T2> { |
|
|||
| 61 | public class Baz { |
|
|||
| 62 |
|
||||
| 63 | } |
|
|||
| 64 |
|
||||
| 65 | } |
|
|||
| 66 |
|
||||
| 67 | public Container() { |
|
|||
| 68 |
|
||||
| 69 | } |
|
|||
| 70 |
|
||||
| 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 | } |
|
|||
| 80 |
|
||||
| 81 | public void AddRange(List<T> items) { |
|
|||
| 82 | Console.WriteLine($"AddRange: {typeof(List<T>)}"); |
|
|||
| 83 | } |
|
|||
| 84 |
|
||||
| 85 | public void AddRange(T[] items) { |
|
|||
| 86 | Console.WriteLine($"AddRange: T[] ofType {typeof(T[])}"); |
|
|||
| 87 | } |
|
|||
| 88 | } |
|
23 | } | |
| 89 |
|
||||
| 90 | public class Program { |
|
24 | public class Program { | |
| 91 |
|
25 | |||
| 92 | static void Main(string[] args) { |
|
26 | static void Main(string[] args) { | |
| 93 | var u1 = new Uri("/some/one"); |
|
|||
| 94 |
|
||||
| 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 |
|
27 | |||
| 119 | container.LoadXmlConfiguration("data/sample.xml"); |
|
28 | using(TraceRegistry.Global.Subscribe(ch => { | |
| 120 |
|
29 | Console.WriteLine($"{ch.Id}: {ch.Source.Name}"); | ||
| 121 | Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}"); |
|
30 | }, true)) { | |
| 122 |
|
31 | Trace<Foo>.Log("Hi!"); | ||
| 123 | stopwatch.Restart(); |
|
32 | Log("Respect!"); | |
| 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); |
|
|||
| 150 | } |
|
33 | } | |
| 151 | } |
|
34 | } | |
| 152 |
|
35 | |||
| 153 |
|
36 | |||
| 154 | } |
|
37 | } | |
| 155 | } |
|
38 | } | |
| @@ -1,143 +1,145 | |||||
| 1 | using System; |
|
1 | using System; | |
| 2 | using System.IO; |
|
2 | using System.IO; | |
| 3 | using System.Reflection; |
|
3 | using System.Reflection; | |
| 4 | using Implab.Diagnostics; |
|
4 | using Implab.Diagnostics; | |
| 5 | using Unity; |
|
5 | using Unity; | |
| 6 |
|
6 | |||
| 7 | namespace Implab.ServiceHost.Unity { |
|
7 | namespace Implab.ServiceHost.Unity { | |
| 8 |
using |
|
8 | using Log = Trace<ContainerBuilder>; | |
| 9 |
|
9 | |||
| 10 | public class ContainerBuilder { |
|
10 | public class ContainerBuilder { | |
| 11 |
|
11 | |||
| 12 | readonly TypeResolver m_resolver; |
|
12 | readonly TypeResolver m_resolver; | |
| 13 |
|
13 | |||
| 14 | readonly IUnityContainer m_container; |
|
14 | readonly IUnityContainer m_container; | |
| 15 |
|
15 | |||
| 16 | readonly ContainerConfigurationSchema m_schema; |
|
16 | readonly ContainerConfigurationSchema m_schema; | |
| 17 |
|
17 | |||
| 18 | Uri m_location; |
|
18 | Uri m_location; | |
| 19 |
|
19 | |||
| 20 | public IUnityContainer Container { |
|
20 | public IUnityContainer Container { | |
| 21 | get { |
|
21 | get { | |
| 22 | return m_container; |
|
22 | return m_container; | |
| 23 | } |
|
23 | } | |
| 24 | } |
|
24 | } | |
| 25 |
|
25 | |||
| 26 | public ContainerBuilder() : this(null, null) { |
|
26 | public ContainerBuilder() : this(null, null) { | |
| 27 | } |
|
27 | } | |
| 28 |
|
28 | |||
| 29 | public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) { |
|
29 | public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) { | |
| 30 | m_container = container ?? new UnityContainer(); |
|
30 | m_container = container ?? new UnityContainer(); | |
| 31 | m_resolver = new TypeResolver(); |
|
31 | m_resolver = new TypeResolver(); | |
| 32 | m_schema = schema ?? ContainerConfigurationSchema.Default; |
|
32 | m_schema = schema ?? ContainerConfigurationSchema.Default; | |
| 33 | } |
|
33 | } | |
| 34 |
|
34 | |||
| 35 | public Type ResolveType(string typeReference) { |
|
35 | public Type ResolveType(string typeReference) { | |
| 36 |
|
|
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 | public void Visit(ITypeRegistration registration) { |
|
41 | public void Visit(ITypeRegistration registration) { | |
| 40 | Safe.ArgumentNotNull(registration, nameof(registration)); |
|
42 | Safe.ArgumentNotNull(registration, nameof(registration)); | |
| 41 |
|
43 | |||
| 42 | var registrationType = registration.GetRegistrationType(this); |
|
44 | var registrationType = registration.GetRegistrationType(this); | |
| 43 | var implementationType = registration.GetImplementationType(this) ?? registrationType; |
|
45 | var implementationType = registration.GetImplementationType(this) ?? registrationType; | |
| 44 |
|
46 | |||
| 45 | if (registrationType == null) |
|
47 | if (registrationType == null) | |
| 46 | throw new Exception($"A type must be specified for the registration {registration.Name}"); |
|
48 | throw new Exception($"A type must be specified for the registration {registration.Name}"); | |
| 47 |
|
49 | |||
| 48 | var builder = new TypeRegistrationBuilder( |
|
50 | var builder = new TypeRegistrationBuilder( | |
| 49 | m_resolver, |
|
51 | m_resolver, | |
| 50 | registrationType, |
|
52 | registrationType, | |
| 51 | implementationType |
|
53 | implementationType | |
| 52 | ); |
|
54 | ); | |
| 53 |
|
55 | |||
| 54 | builder.Lifetime = registration.GetLifetime(this); |
|
56 | builder.Lifetime = registration.GetLifetime(this); | |
| 55 |
|
57 | |||
| 56 | if (registration.MemberInjections != null) { |
|
58 | if (registration.MemberInjections != null) { | |
| 57 | foreach(var member in registration.MemberInjections) |
|
59 | foreach(var member in registration.MemberInjections) | |
| 58 | member.Visit(builder); |
|
60 | member.Visit(builder); | |
| 59 | } |
|
61 | } | |
| 60 |
|
62 | |||
| 61 | m_container.RegisterType( |
|
63 | m_container.RegisterType( | |
| 62 | builder.RegistrationType, |
|
64 | builder.RegistrationType, | |
| 63 | builder.ImplementationType, |
|
65 | builder.ImplementationType, | |
| 64 | registration.Name, |
|
66 | registration.Name, | |
| 65 | builder.Lifetime, |
|
67 | builder.Lifetime, | |
| 66 | builder.Injections |
|
68 | builder.Injections | |
| 67 | ); |
|
69 | ); | |
| 68 | } |
|
70 | } | |
| 69 |
|
71 | |||
| 70 | public void Visit(IInstanceRegistration registration) { |
|
72 | public void Visit(IInstanceRegistration registration) { | |
| 71 | Safe.ArgumentNotNull(registration, nameof(registration)); |
|
73 | Safe.ArgumentNotNull(registration, nameof(registration)); | |
| 72 |
|
74 | |||
| 73 | var registrationType = registration.GetRegistrationType(this); |
|
75 | var registrationType = registration.GetRegistrationType(this); | |
| 74 |
|
76 | |||
| 75 | var builder = new InstanceRegistrationBuilder ( |
|
77 | var builder = new InstanceRegistrationBuilder ( | |
| 76 | m_resolver, |
|
78 | m_resolver, | |
| 77 | registrationType |
|
79 | registrationType | |
| 78 | ); |
|
80 | ); | |
| 79 |
|
81 | |||
| 80 | builder.Lifetime = registration.GetLifetime(this); |
|
82 | builder.Lifetime = registration.GetLifetime(this); | |
| 81 |
|
83 | |||
| 82 | if (registration.MemberInjections != null) { |
|
84 | if (registration.MemberInjections != null) { | |
| 83 | foreach(var member in registration.MemberInjections) |
|
85 | foreach(var member in registration.MemberInjections) | |
| 84 | member.Visit(builder.ValueBuilder); |
|
86 | member.Visit(builder.ValueBuilder); | |
| 85 | } |
|
87 | } | |
| 86 |
|
88 | |||
| 87 | if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null) |
|
89 | if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null) | |
| 88 | throw new Exception($"A type must be specified for the registration {registration.Name}"); |
|
90 | throw new Exception($"A type must be specified for the registration {registration.Name}"); | |
| 89 |
|
91 | |||
| 90 | m_container.RegisterInstance( |
|
92 | m_container.RegisterInstance( | |
| 91 | builder.RegistrationType ?? builder.ValueBuilder.ValueType, |
|
93 | builder.RegistrationType ?? builder.ValueBuilder.ValueType, | |
| 92 | registration.Name, |
|
94 | registration.Name, | |
| 93 | builder.ValueBuilder.Value, |
|
95 | builder.ValueBuilder.Value, | |
| 94 | builder.Lifetime |
|
96 | builder.Lifetime | |
| 95 | ); |
|
97 | ); | |
| 96 | } |
|
98 | } | |
| 97 |
|
99 | |||
| 98 | public void AddNamespace(string ns) { |
|
100 | public void AddNamespace(string ns) { | |
| 99 | m_resolver.AddNamespace(ns); |
|
101 | m_resolver.AddNamespace(ns); | |
| 100 | } |
|
102 | } | |
| 101 |
|
103 | |||
| 102 | public void AddAssembly(string assembly) { |
|
104 | public void AddAssembly(string assembly) { | |
| 103 |
|
105 | |||
| 104 | } |
|
106 | } | |
| 105 |
|
107 | |||
| 106 | /// <summary> |
|
108 | /// <summary> | |
| 107 | /// Includes the confguration. Creates a new <see cref="ContainerBuilder"/>, |
|
109 | /// Includes the confguration. Creates a new <see cref="ContainerBuilder"/>, | |
| 108 | /// and loads the configuration to it. The created builder will share the |
|
110 | /// and loads the configuration to it. The created builder will share the | |
| 109 | /// container and will have its own isolated type resolver. |
|
111 | /// container and will have its own isolated type resolver. | |
| 110 | /// </summary> |
|
112 | /// </summary> | |
| 111 | /// <param name="file">A path to configuration relative to the current configuration.</param> |
|
113 | /// <param name="file">A path to configuration relative to the current configuration.</param> | |
| 112 | public void Include(string file) { |
|
114 | public void Include(string file) { | |
| 113 | var includeContext = new ContainerBuilder(m_container, m_schema); |
|
115 | var includeContext = new ContainerBuilder(m_container, m_schema); | |
| 114 |
|
116 | |||
| 115 | if (m_location != null) { |
|
117 | if (m_location != null) { | |
| 116 | var uri = new Uri(m_location, file); |
|
118 | var uri = new Uri(m_location, file); | |
| 117 | includeContext.LoadConfig(uri); |
|
119 | includeContext.LoadConfig(uri); | |
| 118 | } else { |
|
120 | } else { | |
| 119 | includeContext.LoadConfig(file); |
|
121 | includeContext.LoadConfig(file); | |
| 120 | } |
|
122 | } | |
| 121 | } |
|
123 | } | |
| 122 |
|
124 | |||
| 123 | /// <summary> |
|
125 | /// <summary> | |
| 124 | /// Loads a configuration from the specified local file. |
|
126 | /// Loads a configuration from the specified local file. | |
| 125 | /// </summary> |
|
127 | /// </summary> | |
| 126 | /// <param name="file">The path to the configuration file.</param> |
|
128 | /// <param name="file">The path to the configuration file.</param> | |
| 127 | public void LoadConfig(string file) { |
|
129 | public void LoadConfig(string file) { | |
| 128 | Safe.ArgumentNotEmpty(file, nameof(file)); |
|
130 | Safe.ArgumentNotEmpty(file, nameof(file)); | |
| 129 |
|
131 | |||
| 130 | LoadConfig(new Uri(Path.GetFullPath(file))); |
|
132 | LoadConfig(new Uri(Path.GetFullPath(file))); | |
| 131 | } |
|
133 | } | |
| 132 |
|
134 | |||
| 133 | public void LoadConfig(Uri location) { |
|
135 | public void LoadConfig(Uri location) { | |
| 134 | Safe.ArgumentNotNull(location, nameof(location)); |
|
136 | Safe.ArgumentNotNull(location, nameof(location)); | |
| 135 |
|
137 | |||
| 136 | m_location = location; |
|
138 | m_location = location; | |
| 137 |
|
139 | |||
| 138 | var config = m_schema.LoadConfig(location.ToString()); |
|
140 | var config = m_schema.LoadConfig(location.ToString()); | |
| 139 | config.Visit(this); |
|
141 | config.Visit(this); | |
| 140 | } |
|
142 | } | |
| 141 |
|
143 | |||
| 142 | } |
|
144 | } | |
| 143 | } No newline at end of file |
|
145 | } | |
| @@ -1,17 +1,27 | |||||
| 1 | using System; |
|
1 | using System; | |
| 2 | using System.Diagnostics; |
|
2 | using Stopwatch = System.Diagnostics.Stopwatch; | |
| 3 |
|
3 | |||
| 4 | namespace Implab.Diagnostics { |
|
4 | namespace Implab.Diagnostics { | |
| 5 | public class LogicalOperation { |
|
5 | public class LogicalOperation { | |
| 6 | public Stopwatch OperationStopwatch { get; private set; } |
|
6 | readonly Stopwatch m_stopwatch; | |
| 7 |
|
7 | |||
| 8 | public string Name { get; private set; } |
|
8 | public string Name { get; private set; } | |
| 9 |
|
9 | |||
| 10 | internal LogicalOperation(string name) { |
|
10 | internal LogicalOperation(string name) { | |
| 11 | Name = string.IsNullOrEmpty(name) ? "<unnamed>" : name; |
|
11 | Name = string.IsNullOrEmpty(name) ? "<unnamed>" : name; | |
| 12 |
|
|
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 | public override string ToString() => Name; |
|
25 | public override string ToString() => Name; | |
| 16 | } |
|
26 | } | |
| 17 | } No newline at end of file |
|
27 | } | |
| @@ -1,21 +1,21 | |||||
| 1 | using System; |
|
1 | using System; | |
| 2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
| 3 |
|
3 | |||
| 4 | namespace Implab.Diagnostics { |
|
4 | namespace Implab.Diagnostics { | |
| 5 | public class LogicalOperationScope : IDisposable { |
|
5 | public class LogicalOperationScope : IDisposable { | |
| 6 | readonly TraceSource m_source; |
|
6 | readonly TraceSource m_source; | |
| 7 |
|
7 | |||
| 8 | readonly LogicalOperation m_operation; |
|
8 | readonly LogicalOperation m_operation; | |
| 9 |
|
9 | |||
| 10 | internal LogicalOperationScope(TraceSource source, LogicalOperation operation) { |
|
10 | internal LogicalOperationScope(TraceSource source, LogicalOperation operation) { | |
| 11 | m_source = source; |
|
11 | m_source = source; | |
| 12 | m_operation = operation; |
|
12 | m_operation = operation; | |
| 13 | } |
|
13 | } | |
| 14 |
|
14 | |||
| 15 | public void Dispose() { |
|
15 | public void Dispose() { | |
| 16 |
m_operation. |
|
16 | m_operation.End(); | |
| 17 | Trace.CorrelationManager.StopLogicalOperation(); |
|
17 | Trace.CorrelationManager.StopLogicalOperation(); | |
| 18 | m_source.TraceData(TraceEventType.Information, TraceEventCodes.StopLogicalOperation, m_operation); |
|
18 | m_source.TraceData(TraceEventType.Information, TraceEventCodes.StopLogicalOperation, m_operation); | |
| 19 | } |
|
19 | } | |
| 20 | } |
|
20 | } | |
| 21 | } No newline at end of file |
|
21 | } | |
| @@ -1,114 +1,114 | |||||
| 1 | using System; |
|
1 | using System; | |
| 2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
| 3 | using System.IO; |
|
3 | using System.IO; | |
| 4 |
|
4 | |||
| 5 | namespace Implab.Diagnostics { |
|
5 | namespace Implab.Diagnostics { | |
| 6 | public class SimpleTraceListener : TextWriterTraceListener { |
|
6 | public class SimpleTraceListener : TextWriterTraceListener { | |
| 7 | public SimpleTraceListener() { |
|
7 | public SimpleTraceListener() { | |
| 8 | } |
|
8 | } | |
| 9 |
|
9 | |||
| 10 | public SimpleTraceListener(Stream stream) : base(stream) { |
|
10 | public SimpleTraceListener(Stream stream) : base(stream) { | |
| 11 | } |
|
11 | } | |
| 12 |
|
12 | |||
| 13 | public SimpleTraceListener(TextWriter writer) : base(writer) { |
|
13 | public SimpleTraceListener(TextWriter writer) : base(writer) { | |
| 14 | } |
|
14 | } | |
| 15 |
|
15 | |||
| 16 | public SimpleTraceListener(string fileName) : base(fileName) { |
|
16 | public SimpleTraceListener(string fileName) : base(fileName) { | |
| 17 | } |
|
17 | } | |
| 18 |
|
18 | |||
| 19 | public SimpleTraceListener(Stream stream, string name) : base(stream, name) { |
|
19 | public SimpleTraceListener(Stream stream, string name) : base(stream, name) { | |
| 20 | } |
|
20 | } | |
| 21 |
|
21 | |||
| 22 | public SimpleTraceListener(TextWriter writer, string name) : base(writer, name) { |
|
22 | public SimpleTraceListener(TextWriter writer, string name) : base(writer, name) { | |
| 23 | } |
|
23 | } | |
| 24 |
|
24 | |||
| 25 | public SimpleTraceListener(string fileName, string name) : base(fileName, name) { |
|
25 | public SimpleTraceListener(string fileName, string name) : base(fileName, name) { | |
| 26 | } |
|
26 | } | |
| 27 |
|
27 | |||
| 28 | public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) { |
|
28 | public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) { | |
| 29 | switch (id) { |
|
29 | switch (id) { | |
| 30 | case TraceEventCodes.StartLogicalOperation: |
|
30 | case TraceEventCodes.StartLogicalOperation: | |
| 31 | TraceEvent(eventCache, source, eventType, id, "+{0}", data); |
|
31 | TraceEvent(eventCache, source, eventType, id, "+{0}", data); | |
| 32 | break; |
|
32 | break; | |
| 33 | case TraceEventCodes.StopLogicalOperation: |
|
33 | case TraceEventCodes.StopLogicalOperation: | |
| 34 | TraceEvent(eventCache, source, eventType, id, FormatStopLogicalOperation(data)); |
|
34 | TraceEvent(eventCache, source, eventType, id, FormatStopLogicalOperation(data)); | |
| 35 | break; |
|
35 | break; | |
| 36 | default: |
|
36 | default: | |
| 37 | TraceEvent(eventCache, source, eventType, id, data?.ToString()); |
|
37 | TraceEvent(eventCache, source, eventType, id, data?.ToString()); | |
| 38 | break; |
|
38 | break; | |
| 39 | } |
|
39 | } | |
| 40 | } |
|
40 | } | |
| 41 |
|
41 | |||
| 42 | string FormatStopLogicalOperation(object data) { |
|
42 | string FormatStopLogicalOperation(object data) { | |
| 43 | if (data is LogicalOperation op) { |
|
43 | if (data is LogicalOperation op) { | |
| 44 |
return string.Format("-{0} ({1})", op, FormatTimespan(op. |
|
44 | return string.Format("-{0} ({1})", op, FormatTimespan(op.Elapsed)); | |
| 45 | } else { |
|
45 | } else { | |
| 46 | return data?.ToString(); |
|
46 | return data?.ToString(); | |
| 47 | } |
|
47 | } | |
| 48 | } |
|
48 | } | |
| 49 |
|
49 | |||
| 50 | string FormatTimespan(TimeSpan value) { |
|
50 | string FormatTimespan(TimeSpan value) { | |
| 51 | if (value.TotalSeconds < 10) { |
|
51 | if (value.TotalSeconds < 10) { | |
| 52 | return value.Milliseconds.ToString() + "ms"; |
|
52 | return value.Milliseconds.ToString() + "ms"; | |
| 53 | } else if (value.TotalSeconds < 30) { |
|
53 | } else if (value.TotalSeconds < 30) { | |
| 54 | return string.Format("{0:0.###}s", value.TotalSeconds); |
|
54 | return string.Format("{0:0.###}s", value.TotalSeconds); | |
| 55 | } else { |
|
55 | } else { | |
| 56 | return value.ToString(); |
|
56 | return value.ToString(); | |
| 57 | } |
|
57 | } | |
| 58 | } |
|
58 | } | |
| 59 |
|
59 | |||
| 60 | public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data) { |
|
60 | public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data) { | |
| 61 | var prev = IndentLevel; |
|
61 | var prev = IndentLevel; | |
| 62 | IndentLevel += eventCache.LogicalOperationStack.Count; |
|
62 | IndentLevel += eventCache.LogicalOperationStack.Count; | |
| 63 | try { |
|
63 | try { | |
| 64 | base.TraceData(eventCache, source, eventType, id, data); |
|
64 | base.TraceData(eventCache, source, eventType, id, data); | |
| 65 | } finally { |
|
65 | } finally { | |
| 66 | IndentLevel = prev; |
|
66 | IndentLevel = prev; | |
| 67 | } |
|
67 | } | |
| 68 | } |
|
68 | } | |
| 69 |
|
69 | |||
| 70 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id) { |
|
70 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id) { | |
| 71 | var prev = IndentLevel; |
|
71 | var prev = IndentLevel; | |
| 72 | IndentLevel += eventCache.LogicalOperationStack.Count; |
|
72 | IndentLevel += eventCache.LogicalOperationStack.Count; | |
| 73 | try { |
|
73 | try { | |
| 74 | base.TraceEvent(eventCache, source, eventType, id); |
|
74 | base.TraceEvent(eventCache, source, eventType, id); | |
| 75 | } finally { |
|
75 | } finally { | |
| 76 | IndentLevel = prev; |
|
76 | IndentLevel = prev; | |
| 77 | } |
|
77 | } | |
| 78 | } |
|
78 | } | |
| 79 |
|
79 | |||
| 80 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) { |
|
80 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) { | |
| 81 | TraceEvent(eventCache, source, eventType, id, String.Format(format, args)); |
|
81 | TraceEvent(eventCache, source, eventType, id, String.Format(format, args)); | |
| 82 | } |
|
82 | } | |
| 83 |
|
83 | |||
| 84 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) { |
|
84 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) { | |
| 85 | var prev = IndentLevel; |
|
85 | var prev = IndentLevel; | |
| 86 | IndentLevel += eventCache.LogicalOperationStack.Count; |
|
86 | IndentLevel += eventCache.LogicalOperationStack.Count; | |
| 87 | try { |
|
87 | try { | |
| 88 | LogicalOperation operation = null; |
|
88 | LogicalOperation operation = null; | |
| 89 | if (eventCache.LogicalOperationStack.Count > 0) |
|
89 | if (eventCache.LogicalOperationStack.Count > 0) | |
| 90 | operation = eventCache.LogicalOperationStack.Peek() as LogicalOperation; |
|
90 | operation = eventCache.LogicalOperationStack.Peek() as LogicalOperation; | |
| 91 |
|
91 | |||
| 92 | if (operation != null) { |
|
92 | if (operation != null) { | |
| 93 |
base.TraceData(eventCache, source, eventType, id, FormatTimespan(operation. |
|
93 | base.TraceData(eventCache, source, eventType, id, FormatTimespan(operation.Elapsed) + ": " + message); | |
| 94 | } else { |
|
94 | } else { | |
| 95 | base.TraceData(eventCache, source, eventType, id, message); |
|
95 | base.TraceData(eventCache, source, eventType, id, message); | |
| 96 | } |
|
96 | } | |
| 97 | } finally { |
|
97 | } finally { | |
| 98 | IndentLevel = prev; |
|
98 | IndentLevel = prev; | |
| 99 | } |
|
99 | } | |
| 100 | } |
|
100 | } | |
| 101 |
|
101 | |||
| 102 | public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId) { |
|
102 | public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId) { | |
| 103 | var prev = IndentLevel; |
|
103 | var prev = IndentLevel; | |
| 104 | IndentLevel += eventCache.LogicalOperationStack.Count; |
|
104 | IndentLevel += eventCache.LogicalOperationStack.Count; | |
| 105 | try { |
|
105 | try { | |
| 106 | base.TraceTransfer(eventCache, source, id, message, relatedActivityId); |
|
106 | base.TraceTransfer(eventCache, source, id, message, relatedActivityId); | |
| 107 | } finally { |
|
107 | } finally { | |
| 108 | IndentLevel = prev; |
|
108 | IndentLevel = prev; | |
| 109 | } |
|
109 | } | |
| 110 | } |
|
110 | } | |
| 111 |
|
111 | |||
| 112 |
|
112 | |||
| 113 | } |
|
113 | } | |
| 114 | } No newline at end of file |
|
114 | } | |
| @@ -1,160 +1,192 | |||||
| 1 | // enable System.Diagnostics trace methods |
|
1 | // enable System.Diagnostics trace methods | |
| 2 | #define TRACE |
|
2 | #define TRACE | |
| 3 |
|
3 | |||
| 4 | using System; |
|
4 | using System; | |
| 5 | using System.Collections.Generic; |
|
5 | using System.Collections.Generic; | |
| 6 | using System.Diagnostics; |
|
6 | using System.Diagnostics; | |
| 7 | using System.Linq; |
|
7 | using System.Linq; | |
| 8 | using System.Text; |
|
8 | using System.Text; | |
| 9 | using System.Threading; |
|
9 | using System.Threading; | |
| 10 | using System.Threading.Tasks; |
|
10 | using System.Threading.Tasks; | |
| 11 |
|
11 | |||
| 12 | namespace Implab.Diagnostics { |
|
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 | public static class Trace<T> { |
|
18 | public static class Trace<T> { | |
| 14 |
|
19 | |||
| 15 |
static Lazy<TraceSource> _trace |
|
20 | readonly static Lazy<TraceSource> _trace = new Lazy<TraceSource>(() => TraceSourceChannel<T>.Default.Source); | |
| 16 |
|
||||
| 17 | static int _nextId; |
|
|||
| 18 |
|
21 | |||
| 19 | static TraceSource CreateChannel() { |
|
22 | public static TraceSource TraceSource { get { return _trace.Value; } } | |
| 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; } } |
|
|||
| 29 |
|
23 | |||
| 30 | #if NETFX_TRACE_BUG |
|
24 | #if NETFX_TRACE_BUG | |
| 31 | readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); |
|
25 | readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); | |
| 32 | #endif |
|
26 | #endif | |
| 33 |
|
27 | |||
| 34 | /// <summary> |
|
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 | /// </summary> |
|
39 | /// </summary> | |
| 37 |
public static |
|
40 | public static bool TraceInformation { | |
| 38 | Trace.CorrelationManager.StartLogicalOperation(); |
|
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); | |||
|
|
52 | } | |||
| 40 | } |
|
53 | } | |
| 41 |
|
54 | |||
|
|
55 | ||||
|
|
56 | ||||
| 42 | /// <summary> |
|
57 | /// <summary> | |
| 43 | /// Starts the logical operation with the specified name, this name is usefull in logs. |
|
58 | /// Starts the logical operation with the specified name, this name is usefull in logs. | |
| 44 | /// </summary> |
|
59 | /// </summary> | |
| 45 | /// <param name="name">Name.</param> |
|
60 | /// <param name="name">Name.</param> | |
| 46 | #if NETFX_TRACE_BUG |
|
61 | #if NETFX_TRACE_BUG | |
| 47 | public static void StartLogicalOperation(object name) { |
|
62 | public static void StartLogicalOperation(object name) { | |
| 48 | m_currentOperation.Value = name; |
|
63 | m_currentOperation.Value = name; | |
| 49 | Trace.CorrelationManager.StartLogicalOperation(name); |
|
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 | #else |
|
75 | #else | |
| 52 | public static void StartLogicalOperation(object name) { |
|
76 | public static void StartLogicalOperation(object name) { | |
| 53 | Trace.CorrelationManager.StartLogicalOperation(name); |
|
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 | #endif |
|
87 | #endif | |
| 56 |
|
88 | |||
| 57 | /// <summary> |
|
89 | /// <summary> | |
| 58 | /// Ends the logical operation and restores the previous one. |
|
90 | /// Ends the logical operation and restores the previous one. | |
| 59 | /// </summary> |
|
91 | /// </summary> | |
| 60 | public static void StopLogicalOperation() { |
|
92 | public static void StopLogicalOperation() { | |
| 61 | Trace.CorrelationManager.StopLogicalOperation(); |
|
93 | Trace.CorrelationManager.StopLogicalOperation(); | |
| 62 | } |
|
94 | } | |
| 63 |
|
95 | |||
| 64 | /// <summary> |
|
96 | /// <summary> | |
| 65 | /// Writes a debug message. |
|
97 | /// Writes a debug message. | |
| 66 | /// </summary> |
|
98 | /// </summary> | |
| 67 | /// <param name="format">Format.</param> |
|
99 | /// <param name="format">Format.</param> | |
| 68 | /// <param name="arguments">Arguments.</param> |
|
100 | /// <param name="arguments">Arguments.</param> | |
| 69 | [Conditional("DEBUG")] |
|
101 | [Conditional("DEBUG")] | |
| 70 | public static void Debug(string format, params object[] arguments) { |
|
102 | public static void Debug(string format, params object[] arguments) { | |
| 71 |
|
103 | TraceSource.TraceEvent(TraceEventType.Verbose, 0, format, arguments); | ||
| 72 | } |
|
104 | } | |
| 73 |
|
105 | |||
| 74 | /// <summary> |
|
106 | /// <summary> | |
| 75 | /// Writes an informational message. |
|
107 | /// Writes an informational message. | |
| 76 | /// </summary> |
|
108 | /// </summary> | |
| 77 | /// <param name="format">Format.</param> |
|
109 | /// <param name="format">Format.</param> | |
| 78 | /// <param name="arguments">Arguments.</param> |
|
110 | /// <param name="arguments">Arguments.</param> | |
| 79 | [Conditional("TRACE")] |
|
111 | [Conditional("TRACE")] | |
| 80 | public static void Log(string format, params object[] arguments) { |
|
112 | public static void Log(string format, params object[] arguments) { | |
| 81 | TraceSource.TraceEvent(TraceEventType.Information, 0, format, arguments); |
|
113 | TraceSource.TraceEvent(TraceEventType.Information, 0, format, arguments); | |
| 82 | } |
|
114 | } | |
| 83 |
|
115 | |||
| 84 | /// <summary> |
|
116 | /// <summary> | |
| 85 | /// Writes a warning message. |
|
117 | /// Writes a warning message. | |
| 86 | /// </summary> |
|
118 | /// </summary> | |
| 87 | /// <param name="format">Format.</param> |
|
119 | /// <param name="format">Format.</param> | |
| 88 | /// <param name="arguments">Arguments.</param> |
|
120 | /// <param name="arguments">Arguments.</param> | |
| 89 | public static void Warn(string format, params object[] arguments) { |
|
121 | public static void Warn(string format, params object[] arguments) { | |
| 90 | TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments); |
|
122 | TraceSource.TraceEvent(TraceEventType.Warning, 0, format, arguments); | |
| 91 | } |
|
123 | } | |
| 92 |
|
124 | |||
| 93 | /// <summary> |
|
125 | /// <summary> | |
| 94 | /// Writes a error message. |
|
126 | /// Writes a error message. | |
| 95 | /// </summary> |
|
127 | /// </summary> | |
| 96 | /// <param name="format">Format.</param> |
|
128 | /// <param name="format">Format.</param> | |
| 97 | /// <param name="arguments">Arguments.</param> |
|
129 | /// <param name="arguments">Arguments.</param> | |
| 98 | public static void Error(string format, params object[] arguments) { |
|
130 | public static void Error(string format, params object[] arguments) { | |
| 99 | TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments); |
|
131 | TraceSource.TraceEvent(TraceEventType.Error, 0, format, arguments); | |
| 100 | } |
|
132 | } | |
| 101 |
|
133 | |||
| 102 | public static void Error(Exception err) { |
|
134 | public static void Error(Exception err) { | |
| 103 | TraceSource.TraceData(TraceEventType.Error, 0, err); |
|
135 | TraceSource.TraceData(TraceEventType.Error, 0, err); | |
| 104 | } |
|
136 | } | |
| 105 |
|
137 | |||
| 106 | /// <summary> |
|
138 | /// <summary> | |
| 107 | /// This method save the current activity, and transfers to the specified activity, |
|
139 | /// This method save the current activity, and transfers to the specified activity, | |
| 108 | /// emits <see cref="TraceEventType.Start"/> and returns a scope of the new |
|
140 | /// emits <see cref="TraceEventType.Start"/> and returns a scope of the new | |
| 109 | /// activity. |
|
141 | /// activity. | |
| 110 | /// </summary> |
|
142 | /// </summary> | |
| 111 | /// <param name="activityName">The name of the new activity/</param> |
|
143 | /// <param name="activityName">The name of the new activity/</param> | |
| 112 | /// <param name="activityId">The identifier of the activity to which |
|
144 | /// <param name="activityId">The identifier of the activity to which | |
| 113 | /// the control will be transferred</param> |
|
145 | /// the control will be transferred</param> | |
| 114 | /// <returns>A scope of the new activity, dispose it to transfer |
|
146 | /// <returns>A scope of the new activity, dispose it to transfer | |
| 115 | /// the control back to the original activity.</returns> |
|
147 | /// the control back to the original activity.</returns> | |
| 116 | public static ActivityScope TransferActivity(string activityName, Guid activityId) { |
|
148 | public static ActivityScope TransferActivity(string activityName, Guid activityId) { | |
| 117 | var prev = Trace.CorrelationManager.ActivityId; |
|
149 | var prev = Trace.CorrelationManager.ActivityId; | |
| 118 |
|
150 | |||
| 119 | TraceSource.TraceTransfer(0, "Transfer", activityId); |
|
151 | TraceSource.TraceTransfer(0, "Transfer", activityId); | |
| 120 | Trace.CorrelationManager.ActivityId = activityId; |
|
152 | Trace.CorrelationManager.ActivityId = activityId; | |
| 121 | TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); |
|
153 | TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); | |
| 122 |
|
154 | |||
| 123 | return new ActivityScope(TraceSource, prev, 0, activityName); |
|
155 | return new ActivityScope(TraceSource, prev, 0, activityName); | |
| 124 | } |
|
156 | } | |
| 125 |
|
157 | |||
| 126 | /// <summary> |
|
158 | /// <summary> | |
| 127 | /// Emits <see cref="TraceEventType.Start"/> and returns a scope of the |
|
159 | /// Emits <see cref="TraceEventType.Start"/> and returns a scope of the | |
| 128 | /// activity. |
|
160 | /// activity. | |
| 129 | /// </summary> |
|
161 | /// </summary> | |
| 130 | /// <param name="activityName">The name of the activity to start</param> |
|
162 | /// <param name="activityName">The name of the activity to start</param> | |
| 131 | /// <returns>A scope of the new activity, dispose it to emit |
|
163 | /// <returns>A scope of the new activity, dispose it to emit | |
| 132 | /// <see cref="TraceEventType.Stop"/> for the current activity.</returns> |
|
164 | /// <see cref="TraceEventType.Stop"/> for the current activity.</returns> | |
| 133 | public static ActivityScope StartActivity(string activityName) { |
|
165 | public static ActivityScope StartActivity(string activityName) { | |
| 134 | if (Trace.CorrelationManager.ActivityId == Guid.Empty) |
|
166 | if (Trace.CorrelationManager.ActivityId == Guid.Empty) | |
| 135 | Trace.CorrelationManager.ActivityId = Guid.NewGuid(); |
|
167 | Trace.CorrelationManager.ActivityId = Guid.NewGuid(); | |
| 136 |
|
168 | |||
| 137 | var prev = Trace.CorrelationManager.ActivityId; |
|
169 | var prev = Trace.CorrelationManager.ActivityId; | |
| 138 |
|
170 | |||
| 139 | TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); |
|
171 | TraceSource.TraceEvent(TraceEventType.Start, 0, activityName); | |
| 140 | return new ActivityScope(TraceSource, prev, 0, activityName); |
|
172 | return new ActivityScope(TraceSource, prev, 0, activityName); | |
| 141 | } |
|
173 | } | |
| 142 |
|
174 | |||
| 143 | /// <summary> |
|
175 | /// <summary> | |
| 144 | /// Creates new <see cref="LogicalOperation(string)"/> and calls |
|
176 | /// Creates new <see cref="LogicalOperation(string)"/> and calls | |
| 145 | /// to <see cref="CorrelationManager.StartLogicalOperation(object)"/> |
|
177 | /// to <see cref="CorrelationManager.StartLogicalOperation(object)"/> | |
| 146 | /// passing the created operation as identity. Calls |
|
178 | /// passing the created operation as identity. Calls | |
| 147 | /// <see cref="TraceSource.TraceData(TraceEventType, int, object)"/> |
|
179 | /// <see cref="TraceSource.TraceData(TraceEventType, int, object)"/> | |
| 148 | /// to notify listeners on operation start. |
|
180 | /// to notify listeners on operation start. | |
| 149 | /// </summary> |
|
181 | /// </summary> | |
| 150 | /// <param name="name">The name of the logical operation.</param> |
|
182 | /// <param name="name">The name of the logical operation.</param> | |
| 151 | /// <returns>Logical operation scope, disposing it will stop |
|
183 | /// <returns>Logical operation scope, disposing it will stop | |
| 152 | /// logical operation and notify trace listeners.</returns> |
|
184 | /// logical operation and notify trace listeners.</returns> | |
| 153 | public static LogicalOperationScope LogicalOperation(string name) { |
|
185 | public static LogicalOperationScope LogicalOperation(string name) { | |
| 154 | var operation = new LogicalOperation(name); |
|
186 | var operation = new LogicalOperation(name); | |
| 155 | TraceSource.TraceData(TraceEventType.Information, TraceEventCodes.StartLogicalOperation, operation); |
|
187 | TraceSource.TraceData(TraceEventType.Information, TraceEventCodes.StartLogicalOperation, operation); | |
| 156 | StartLogicalOperation(operation); |
|
188 | StartLogicalOperation(operation); | |
| 157 | return new LogicalOperationScope(TraceSource, operation); |
|
189 | return new LogicalOperationScope(TraceSource, operation); | |
| 158 | } |
|
190 | } | |
| 159 | } |
|
191 | } | |
| 160 | } |
|
192 | } | |
| @@ -1,10 +1,11 | |||||
| 1 | using System; |
|
1 | using System; | |
| 2 |
|
2 | |||
| 3 | namespace Implab.Diagnostics { |
|
3 | namespace Implab.Diagnostics { | |
| 4 | /// <summary> |
|
4 | /// <summary> | |
| 5 | /// Used to mark class which uses <see cref="Trace{T}"/> class to trace it's events |
|
5 | /// Used to mark class which uses <see cref="Trace{T}"/> class to trace it's events | |
| 6 | /// </summary> |
|
6 | /// </summary> | |
| 7 | [AttributeUsage(AttributeTargets.Class)] |
|
7 | [AttributeUsage(AttributeTargets.Class)] | |
|
|
8 | [Obsolete("Use TraceRegistry to monitor trace sources")] | |||
| 8 | public class TraceSourceAttribute : Attribute { |
|
9 | public class TraceSourceAttribute : Attribute { | |
| 9 | } |
|
10 | } | |
| 10 | } |
|
11 | } | |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now
