diff Implab/Diagnostics/TextListenerBase.cs @ 43:7c2369f580b8

improved tracing, TextListenerBase can be bound to logical operation scope.
author cin
date Wed, 16 Apr 2014 10:12:56 +0400
parents fe33f4e02ad5
children b181f7bcb259
line wrap: on
line diff
--- a/Implab/Diagnostics/TextListenerBase.cs	Wed Apr 16 00:33:09 2014 +0400
+++ b/Implab/Diagnostics/TextListenerBase.cs	Wed Apr 16 10:12:56 2014 +0400
@@ -7,9 +7,15 @@
     public abstract class TextListenerBase : ServiceLocator, IEventTextFormatter<object>, IEventTextFormatter<TraceEvent> {
 
         readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>();
+        readonly LogicalOperation m_boundOperation;
+        readonly int m_baseIndent;
 
-        protected TextListenerBase() {
+        protected TextListenerBase(bool local) {
             Register(this);
+            if (local) {
+                m_boundOperation = TraceContext.Current.CurrentOperation;
+                m_baseIndent = Math.Max(0, m_boundOperation.Level - 1);
+            }
         }
 
         public void Subscribe(Type eventType) {
@@ -32,7 +38,12 @@
                 var formatter = GetService<IEventTextFormatter<TEvent>>();
 
                 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
-                    WriteEntry((TraceContext)sender, formatter.Format((TraceContext)sender, args.Value));
+                    TraceContext context = (TraceContext)sender;
+                    var text = formatter.Format(context, args.Value);
+                    text.indent -= m_baseIndent;
+
+                    if (IsRelated(context.CurrentOperation))
+                        WriteEntry(context, text);
                 };
 
                 if (m_subscriptions.ContainsKey(channel))
@@ -48,6 +59,15 @@
             }
         }
 
+        public bool IsRelated(LogicalOperation op) {
+            if (m_boundOperation == null)
+                return true;
+
+            while (op != m_boundOperation && op.Level > m_boundOperation.Level)
+                op = op.Parent;
+            return op == m_boundOperation;
+        }
+
         public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) {
             if (channel == null)
                 throw new ArgumentNullException("channel");