Author: cschneider Date: Fri Oct 7 13:47:03 2011 New Revision: 1180036 URL: http://svn.apache.org/viewvc?rev=1180036&view=rev Log: CAMEL-4500 Add JMX trace notifications
Added: camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/JMXNotificationTraceEventHandler.java Modified: camel/branches/camel-2.8.x/camel-core/pom.xml camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTracer.java camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/Tracer.java Modified: camel/branches/camel-2.8.x/camel-core/pom.xml URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/camel-core/pom.xml?rev=1180036&r1=1180035&r2=1180036&view=diff ============================================================================== --- camel/branches/camel-2.8.x/camel-core/pom.xml (original) +++ camel/branches/camel-2.8.x/camel-core/pom.xml Fri Oct 7 13:47:03 2011 @@ -86,10 +86,6 @@ <!-- we only need spring-context.jar as optional as we need the JMX export annotations --> <exclusion> <groupId>org.springframework</groupId> - <artifactId>spring-core</artifactId> - </exclusion> - <exclusion> - <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> Modified: camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java?rev=1180036&r1=1180035&r2=1180036&view=diff ============================================================================== --- camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java (original) +++ camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java Fri Oct 7 13:47:03 2011 @@ -30,6 +30,8 @@ import org.slf4j.LoggerFactory; import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler; +import org.springframework.jmx.export.notification.ModelMBeanNotificationPublisher; +import org.springframework.jmx.export.notification.NotificationPublisherAware; /** * An assembler to assemble a {@link javax.management.modelmbean.RequiredModelMBean} which can be used @@ -78,6 +80,11 @@ public class JmxMBeanAssembler { } catch (InvalidTargetObjectTypeException e) { throw new JMException(e.getMessage()); } + + if (obj instanceof NotificationPublisherAware) { + NotificationPublisherAware publishereAwareObj = (NotificationPublisherAware) obj; + publishereAwareObj.setNotificationPublisher(new ModelMBeanNotificationPublisher(mbean, name, obj)); + } return mbean; } Added: camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/JMXNotificationTraceEventHandler.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/JMXNotificationTraceEventHandler.java?rev=1180036&view=auto ============================================================================== --- camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/JMXNotificationTraceEventHandler.java (added) +++ camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/JMXNotificationTraceEventHandler.java Fri Oct 7 13:47:03 2011 @@ -0,0 +1,114 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.management.mbean; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.management.Notification; + +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.processor.Traceable; +import org.apache.camel.processor.interceptor.TraceEventHandler; +import org.apache.camel.processor.interceptor.TraceInterceptor; +import org.apache.camel.processor.interceptor.Tracer; +import org.apache.camel.util.MessageHelper; +import org.springframework.jmx.export.notification.NotificationPublisher; +import org.springframework.jmx.export.notification.NotificationPublisherAware; + +public final class JMXNotificationTraceEventHandler implements TraceEventHandler, NotificationPublisherAware { + private static final int MAX_MESSAGE_LENGTH = 60; + private long num; + private NotificationPublisher notificationSender; + private Tracer tracer; + + public JMXNotificationTraceEventHandler(Tracer tracer) { + this.tracer = tracer; + } + + @SuppressWarnings("rawtypes") + public void traceExchangeOut(ProcessorDefinition node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange, Object traceState) throws Exception { + } + + @SuppressWarnings("rawtypes") + public Object traceExchangeIn(ProcessorDefinition node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange) throws Exception { + return null; + } + + @SuppressWarnings("rawtypes") + public void traceExchange(ProcessorDefinition node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange) throws Exception { + if (notificationSender != null && tracer.isJmxTraceNotifications()) { + String body = MessageHelper.extractBodyForLogging(exchange.getIn(), "", false, tracer.getTraceBodySize()); + + if (body == null) { + body = ""; + } + String message = body.substring(0, Math.min(body.length(), MAX_MESSAGE_LENGTH)); + Map tm = createTraceMessage(node, exchange, body); + + Notification notification = new Notification("TraceNotification", exchange.toString(), num++, System.currentTimeMillis(), message); + notification.setUserData(tm); + + notificationSender.sendNotification(notification); + } + + } + + private Map<String, Object> createTraceMessage(ProcessorDefinition<?> node, Exchange exchange, String body) { + Map<String, Object> mi = new HashMap<String, Object>(); + mi.put("ExchangeId", exchange.getExchangeId()); + mi.put("EndpointURI", getEndpointUri(node)); + mi.put("TimeStamp", new Date(System.currentTimeMillis())); + mi.put("Body", body); + + Message message = exchange.getIn(); + Map<String, Object> sHeaders = message.getHeaders(); + Map<String, Object> sProperties = exchange.getProperties(); + + Map<String, String> headers = new HashMap<String, String>(); + for (String key : sHeaders.keySet()) { + headers.put(key, message.getHeader(key, String.class)); + } + mi.put("Headers", headers); + + Map<String, String> properties = new HashMap<String, String>(); + for (String key : sProperties.keySet()) { + properties.put(key, exchange.getProperty(key, String.class)); + } + mi.put("Properties", properties); + return mi; + } + + private String getEndpointUri(ProcessorDefinition<?> node) { + if (node instanceof Traceable) { + Traceable tr = (Traceable)node; + return tr.getTraceLabel(); + } else { + return node.getLabel(); + } + } + + @Override + public void setNotificationPublisher(NotificationPublisher notificationPublisher) { + this.notificationSender = notificationPublisher; + } + +} Modified: camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTracer.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTracer.java?rev=1180036&r1=1180035&r2=1180036&view=diff ============================================================================== --- camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTracer.java (original) +++ camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTracer.java Fri Oct 7 13:47:03 2011 @@ -22,19 +22,31 @@ import org.apache.camel.processor.interc import org.apache.camel.spi.ManagementStrategy; import org.apache.camel.util.ObjectHelper; import org.springframework.jmx.export.annotation.ManagedAttribute; +import org.springframework.jmx.export.annotation.ManagedNotification; +import org.springframework.jmx.export.annotation.ManagedNotifications; import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.jmx.export.notification.NotificationPublisher; +import org.springframework.jmx.export.notification.NotificationPublisherAware; /** * @version */ @ManagedResource(description = "Managed Tracer") -public class ManagedTracer { +@ManagedNotifications(@ManagedNotification(name = "javax.management.Notification", +description = "Fine grained trace events", +notificationTypes = {"TraceNotification"})) +public class ManagedTracer implements NotificationPublisherAware { private final CamelContext camelContext; private final Tracer tracer; + private JMXNotificationTraceEventHandler jmxTraceHandler; public ManagedTracer(CamelContext camelContext, Tracer tracer) { this.camelContext = camelContext; this.tracer = tracer; + this.jmxTraceHandler = new JMXNotificationTraceEventHandler(tracer); + if (this.tracer.getTraceHandler() == null) { + this.tracer.setTraceHandler(this.jmxTraceHandler); + } } public void init(ManagementStrategy strategy) { @@ -409,5 +421,30 @@ public class ManagedTracer { } tracer.getDefaultTraceFormatter().setMaxChars(maxChars); } + + @ManagedAttribute(description = "Should trace events be sent as jmx notifications") + public boolean isJmxTraceNotifications() { + return this.tracer.isJmxTraceNotifications(); + } + + @ManagedAttribute + public void setJmxTraceNotifications(boolean jmxTraceNotifications) { + this.tracer.setJmxTraceNotifications(jmxTraceNotifications); + } + + @ManagedAttribute(description = "Maximum size of a message body for trace notification") + public int getTraceBodySize() { + return this.tracer.getTraceBodySize(); + } + + @ManagedAttribute + public void setTraceBodySize(int traceBodySize) { + this.tracer.setTraceBodySize(traceBodySize); + } + + @Override + public void setNotificationPublisher(NotificationPublisher notificationPublisher) { + this.jmxTraceHandler.setNotificationPublisher(notificationPublisher); + } } Modified: camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/Tracer.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/Tracer.java?rev=1180036&r1=1180035&r2=1180036&view=diff ============================================================================== --- camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/Tracer.java (original) +++ camel/branches/camel-2.8.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/Tracer.java Fri Oct 7 13:47:03 2011 @@ -54,6 +54,8 @@ public class Tracer implements Intercept private TraceInterceptorFactory traceInterceptorFactory = new DefaultTraceInterceptorFactory(); private TraceEventHandler traceHandler; private String jpaTraceEventMessageClassName = JPA_TRACE_EVENT_MESSAGE; + private boolean jmxTraceNotifications; + private int traceBodySize; /** * Creates a new tracer. @@ -306,6 +308,22 @@ public class Tracer implements Intercept this.jpaTraceEventMessageClassName = jpaTraceEventMessageClassName; } + public boolean isJmxTraceNotifications() { + return jmxTraceNotifications; + } + + public void setJmxTraceNotifications(boolean jmxTraceNotifications) { + this.jmxTraceNotifications = jmxTraceNotifications; + } + + public int getTraceBodySize() { + return traceBodySize; + } + + public void setTraceBodySize(int traceBodySize) { + this.traceBodySize = traceBodySize; + } + @Override public String toString() { return "Tracer";