Author: davsclaus
Date: Mon Mar 25 17:33:25 2013
New Revision: 1460769

URL: http://svn.apache.org/r1460769
Log:
CAMEL-6149: Added trace filter option to backlog tracer

Added:
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerFilterTest.java
      - copied, changed from r1460757, 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerPatternTest.java
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTracerBacklogMBean.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracer.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracerInterceptor.java
    
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
    
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTracerBacklogMBean.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTracerBacklogMBean.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTracerBacklogMBean.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTracerBacklogMBean.java
 Mon Mar 25 17:33:25 2013
@@ -47,6 +47,12 @@ public interface ManagedTracerBacklogMBe
     @ManagedAttribute(description = "To filter tracing by nodes (pattern)")
     String getTracePattern();
 
+    @ManagedAttribute(description = "To filter tracing by predicate (uses 
simple language by default)")
+    void setTraceFilter(String predicate);
+
+    @ManagedAttribute(description = "To filter tracing by predicate (uses 
simple language by default)")
+    String getTraceFilter();
+
     @ManagedAttribute(description = "Number of total traced messages")
     long getTraceCounter();
 

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
 Mon Mar 25 17:33:25 2013
@@ -86,6 +86,14 @@ public class ManagedBacklogTracer implem
         return backlogTracer.getTracePattern();
     }
 
+    public void setTraceFilter(String predicate) {
+        backlogTracer.setTraceFilter(predicate);
+    }
+
+    public String getTraceFilter() {
+        return backlogTracer.getTraceFilter();
+    }
+
     public long getTraceCounter() {
         return backlogTracer.getTraceCounter();
     }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracer.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracer.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracer.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracer.java
 Mon Mar 25 17:33:25 2013
@@ -25,6 +25,8 @@ import java.util.concurrent.ArrayBlockin
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.api.management.mbean.BacklogTracerEventMessage;
 import org.apache.camel.model.ProcessorDefinition;
@@ -35,6 +37,9 @@ import org.apache.camel.spi.InterceptStr
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.EndpointHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A tracer used for message tracing, storing a copy of the message details in 
a backlog.
@@ -44,6 +49,7 @@ import org.apache.camel.util.EndpointHel
  */
 public class BacklogTracer extends ServiceSupport implements InterceptStrategy 
{
 
+    private static final transient Logger LOG = 
LoggerFactory.getLogger(BacklogTracer.class);
     // lets limit the tracer to 100 thousand messages in total
     public static final int MAX_BACKLOG_SIZE = 100 * 1000;
     private final CamelContext camelContext;
@@ -60,6 +66,8 @@ public class BacklogTracer extends Servi
     // a pattern to filter tracing nodes
     private String tracePattern;
     private String[] patterns;
+    private String traceFilter;
+    private Predicate predicate;
     // remember the processors we are tracing, which we need later
     private final Set<ProcessorDefinition<?>> processors = new 
HashSet<ProcessorDefinition<?>>();
 
@@ -110,34 +118,52 @@ public class BacklogTracer extends Servi
      * Whether or not to trace the given processor definition.
      *
      * @param definition the processor definition
+     * @param exchange   the exchange
      * @return <tt>true</tt> to trace, <tt>false</tt> to skip tracing
      */
-    public boolean shouldTrace(ProcessorDefinition<?> definition) {
+    public boolean shouldTrace(ProcessorDefinition<?> definition, Exchange 
exchange) {
         if (!enabled) {
             return false;
         }
 
+        boolean pattern = true;
+        boolean filter = true;
+
         if (patterns != null) {
-            for (String pattern : patterns) {
-                // match either route id, or node id
-                String id = definition.getId();
-                // use matchPattern method from endpoint helper that has a 
good matcher we use in Camel
+            pattern = shouldTracePattern(definition);
+        }
+        if (predicate != null) {
+            filter = shouldTraceFilter(exchange);
+        }
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Should trace evaluated {} -> pattern: {}, filter: {}", 
new Object[]{definition.getId(), pattern, filter});
+        }
+        return pattern && filter;
+    }
+
+    private boolean shouldTracePattern(ProcessorDefinition<?> definition) {
+        for (String pattern : patterns) {
+            // match either route id, or node id
+            String id = definition.getId();
+            // use matchPattern method from endpoint helper that has a good 
matcher we use in Camel
+            if (EndpointHelper.matchPattern(id, pattern)) {
+                return true;
+            }
+            RouteDefinition route = 
ProcessorDefinitionHelper.getRoute(definition);
+            if (route != null) {
+                id = route.getId();
                 if (EndpointHelper.matchPattern(id, pattern)) {
                     return true;
                 }
-                RouteDefinition route = 
ProcessorDefinitionHelper.getRoute(definition);
-                if (route != null) {
-                    id = route.getId();
-                    if (EndpointHelper.matchPattern(id, pattern)) {
-                        return true;
-                    }
-                }
             }
-            // not matched the pattern
-            return false;
         }
+        // not matched the pattern
+        return false;
+    }
 
-        return true;
+    private boolean shouldTraceFilter(Exchange exchange) {
+        return predicate.matches(exchange);
     }
 
     public boolean isEnabled() {
@@ -212,6 +238,23 @@ public class BacklogTracer extends Servi
         }
     }
 
+    public String getTraceFilter() {
+        return traceFilter;
+    }
+
+    public void setTraceFilter(String filter) {
+        this.traceFilter = filter;
+        if (filter != null) {
+            // assume simple language
+            String name = ObjectHelper.before(filter, ":");
+            if (name == null) {
+                // use simple language by default
+                name = "simple";
+            }
+            predicate = 
camelContext.resolveLanguage(name).createPredicate(filter);
+        }
+    }
+
     public long getTraceCounter() {
         return traceCounter.get();
     }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracerInterceptor.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracerInterceptor.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracerInterceptor.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogTracerInterceptor.java
 Mon Mar 25 17:33:25 2013
@@ -52,7 +52,7 @@ public class BacklogTracerInterceptor ex
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         try {
-            if (backlogTracer.shouldTrace(processorDefinition)) {
+            if (backlogTracer.shouldTrace(processorDefinition, exchange)) {
                 // ensure there is space on the queue
                 int drain = queue.size() - backlogTracer.getBacklogSize();
                 // and we need room for ourselves and possible also a first 
pseudo message as well

Copied: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerFilterTest.java
 (from r1460757, 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerPatternTest.java)
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerFilterTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerFilterTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerPatternTest.java&r1=1460757&r2=1460769&rev=1460769&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerPatternTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/BacklogTracerFilterTest.java
 Mon Mar 25 17:33:25 2013
@@ -25,10 +25,10 @@ import org.apache.camel.Exchange;
 import org.apache.camel.api.management.mbean.BacklogTracerEventMessage;
 import org.apache.camel.builder.RouteBuilder;
 
-public class BacklogTracerPatternTest extends ManagementTestSupport {
+public class BacklogTracerFilterTest extends ManagementTestSupport {
 
     @SuppressWarnings("unchecked")
-    public void testBacklogTracerPattern() throws Exception {
+    public void testBacklogTracerFilter() throws Exception {
         MBeanServer mbeanServer = getMBeanServer();
         ObjectName on = new 
ObjectName("org.apache.camel:context=localhost/camel-1,type=tracer,name=BacklogTracer");
         assertNotNull(on);
@@ -40,8 +40,8 @@ public class BacklogTracerPatternTest ex
         Integer size = (Integer) mbeanServer.getAttribute(on, "BacklogSize");
         assertEquals("Should be 1000", 1000, size.intValue());
 
-        // set the pattern to match only foo*
-        mbeanServer.setAttribute(on, new Attribute("TracePattern", "foo*"));
+        // set the filter to match only if header foo exists
+        mbeanServer.setAttribute(on, new Attribute("TraceFilter", 
"${header.foo} != null"));
 
         // enable it
         mbeanServer.setAttribute(on, new Attribute("Enabled", Boolean.TRUE));
@@ -50,36 +50,43 @@ public class BacklogTracerPatternTest ex
         getMockEndpoint("mock:bar").expectedMessageCount(2);
 
         template.sendBody("direct:start", "Hello World");
-        template.sendBody("direct:start", "Bye World");
+        template.sendBodyAndHeader("direct:start", "Bye World", "foo", 123);
 
         assertMockEndpointsSatisfied();
 
         List<Exchange> exchanges = 
getMockEndpoint("mock:foo").getReceivedExchanges();
 
-        List<BacklogTracerEventMessage> events = 
(List<BacklogTracerEventMessage>) mbeanServer.invoke(on, "dumpTracedMessages",
-                new Object[]{"foo"}, new String[]{"java.lang.String"});
+        List<BacklogTracerEventMessage> events = 
(List<BacklogTracerEventMessage>) mbeanServer.invoke(on, 
"dumpAllTracedMessages", null, null);
 
         assertNotNull(events);
-        assertEquals(2, events.size());
+        assertEquals(3, events.size());
 
-        BacklogTracerEventMessage event1 = events.get(0);
+        BacklogTracerEventMessage event = events.get(0);
+        assertEquals(null, event.getToNode());
+        assertEquals("    <message exchangeId=\"" + 
exchanges.get(1).getExchangeId() + "\">\n"
+                + "      <headers>\n"
+                + "        <header key=\"foo\" 
type=\"java.lang.Integer\">123</header>\n"
+                + "      </headers>\n"
+                + "      <body type=\"java.lang.String\">Bye World</body>\n"
+                + "    </message>", event.getMessageAsXml());
+
+        BacklogTracerEventMessage event1 = events.get(1);
         assertEquals("foo", event1.getToNode());
-        assertEquals("    <message exchangeId=\"" + 
exchanges.get(0).getExchangeId() + "\">\n"
-                + "      <body type=\"java.lang.String\">Hello World</body>\n"
+        assertEquals("    <message exchangeId=\"" + 
exchanges.get(1).getExchangeId() + "\">\n"
+                + "      <headers>\n"
+                + "        <header key=\"foo\" 
type=\"java.lang.Integer\">123</header>\n"
+                + "      </headers>\n"
+                + "      <body type=\"java.lang.String\">Bye World</body>\n"
                 + "    </message>", event1.getMessageAsXml());
 
-        BacklogTracerEventMessage event2 = events.get(1);
-        assertEquals("foo", event2.getToNode());
+        BacklogTracerEventMessage event2 = events.get(2);
+        assertEquals("bar", event2.getToNode());
         assertEquals("    <message exchangeId=\"" + 
exchanges.get(1).getExchangeId() + "\">\n"
+                + "      <headers>\n"
+                + "        <header key=\"foo\" 
type=\"java.lang.Integer\">123</header>\n"
+                + "      </headers>\n"
                 + "      <body type=\"java.lang.String\">Bye World</body>\n"
                 + "    </message>", event2.getMessageAsXml());
-
-        // there should be no messages on bar
-
-        events = (List<BacklogTracerEventMessage>) mbeanServer.invoke(on, 
"dumpTracedMessages",
-                new Object[]{"bar"}, new String[]{"java.lang.String"});
-        assertNotNull(events);
-        assertEquals(0, events.size());
     }
 
     @Override

Modified: 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
 (original)
+++ 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
 Mon Mar 25 17:33:25 2013
@@ -53,6 +53,7 @@ public class BacklogTracerInfo extends O
         System.out.println("BacklogTracer context:\t\t" + camel.getName());
         System.out.println("BacklogTracer enabled:\t\t" + 
backlogTracer.isEnabled());
         System.out.println("BacklogTracer pattern:\t\t" + 
(backlogTracer.getTracePattern() != null ? backlogTracer.getTracePattern() : 
""));
+        System.out.println("BacklogTracer filter:\t\t" + 
(backlogTracer.getTraceFilter() != null ? backlogTracer.getTraceFilter() : ""));
         System.out.println("BacklogTracer removeOnDump:\t" + 
backlogTracer.isRemoveOnDump());
         System.out.println("BacklogTracer backlogSize:\t" + 
backlogTracer.getBacklogSize());
         System.out.println("BacklogTracer tracerCount:\t" + 
backlogTracer.getTraceCounter());

Modified: 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java?rev=1460769&r1=1460768&r2=1460769&view=diff
==============================================================================
--- 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
 (original)
+++ 
camel/trunk/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
 Mon Mar 25 17:33:25 2013
@@ -33,10 +33,14 @@ public class BacklogTracerStart extends 
             required = true, multiValued = false)
     String context;
 
-    @Argument(index = 1, name = "pattern", description = "To trace messages 
only for nodes or routes matching the given pattern (default is all)",
+    @Option(name = "--pattern", aliases = "-p", description = "To trace 
messages only for nodes or routes matching the given pattern (default is all)",
             required = false, multiValued = false)
     String pattern;
 
+    @Option(name = "--filter", aliases = "-f", description = "To trace 
messages only for nodes or routes matching the given filter (using simple 
language by default)",
+            required = false, multiValued = false)
+    String filter;
+
     @Option(name = "--backlogSize", aliases = "-s", description = "Number of 
maximum traced messages in total to keep in the backlog (FIFO queue)",
             required = false, multiValued = false, valueToShowInHelp = "1000")
     Integer backlogSize;
@@ -71,12 +75,10 @@ public class BacklogTracerStart extends 
         if (removeOnDump != null) {
             backlogTracer.setRemoveOnDump(removeOnDump);
         }
-        if (pattern != null) {
-            backlogTracer.setTracePattern(pattern);
-            System.out.println("BacklogTracer started on " + camel.getName() + 
" using pattern: " + pattern + " with size: " + backlogTracer.getBacklogSize());
-        } else {
-            System.out.println("BacklogTracer started on " + camel.getName() + 
" with size: " + backlogTracer.getBacklogSize());
-        }
+        backlogTracer.setTracePattern(pattern);
+        backlogTracer.setTraceFilter(filter);
+
+        System.out.println("BacklogTracer started on " + camel.getName() + " 
with size: " + backlogTracer.getBacklogSize());
         return null;
     }
 


Reply via email to