/** * 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.component.metrics.messagehistory; import java.util.Date; import java.util.concurrent.TimeUnit; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.MessageHistory; import org.apache.camel.NamedNode; import org.apache.camel.NonManagedService; import org.apache.camel.StaticService; import org.apache.camel.spi.MessageHistoryFactory; import org.apache.camel.support.ServiceSupport; import org.apache.camel.util.ObjectHelper; /** * A factory to setup and use {@link MetricsMessageHistory} as message history implementation. */ public class MetricsMessageHistoryFactory extends ServiceSupport implements CamelContextAware, StaticService, NonManagedService, MessageHistoryFactory { private CamelContext camelContext; private MetricsMessageHistoryService messageHistoryService; private MetricRegistry metricsRegistry; private boolean useJmx; private String jmxDomain = "org.apache.camel.metrics"; private boolean prettyPrint; private TimeUnit rateUnit = TimeUnit.SECONDS; private TimeUnit durationUnit = TimeUnit.MILLISECONDS; private String namePattern = "##name##.##routeId##.##id##.##type##"; @Override public CamelContext getCamelContext() { return camelContext; } @Override public void setCamelContext(CamelContext camelContext) { this.camelContext = camelContext; } public MetricRegistry getMetricsRegistry() { return metricsRegistry; } /** * To use a specific {@link com.codahale.metrics.MetricRegistry} instance. * <p/> * If no instance has been configured, then Camel will create a shared instance to be used. */ public void setMetricsRegistry(MetricRegistry metricsRegistry) { this.metricsRegistry = metricsRegistry; } public boolean isUseJmx() { return useJmx; } /** * Whether to use JMX reported to enlist JMX MBeans with the metrics statistics. */ public void setUseJmx(boolean useJmx) { this.useJmx = useJmx; } public String getJmxDomain() { return jmxDomain; } /** * The JMX domain name to use for the enlisted JMX MBeans. */ public void setJmxDomain(String jmxDomain) { this.jmxDomain = jmxDomain; } public boolean isPrettyPrint() { return prettyPrint; } /** * Whether to use pretty print when outputting JSon */ public void setPrettyPrint(boolean prettyPrint) { this.prettyPrint = prettyPrint; } public TimeUnit getRateUnit() { return rateUnit; } /** * Sets the time unit to use for requests per unit (eg requests per second) */ public void setRateUnit(TimeUnit rateUnit) { this.rateUnit = rateUnit; } public TimeUnit getDurationUnit() { return durationUnit; } /** * Sets the time unit to use for timing the duration of processing a message in the route */ public void setDurationUnit(TimeUnit durationUnit) { this.durationUnit = durationUnit; } @Override public MessageHistory newMessageHistory(String routeId, NamedNode namedNode, Date date) { Timer timer = metricsRegistry.timer(createName("history", routeId, namedNode.getId())); return new MetricsMessageHistory(routeId, namedNode, timer); } private String createName(String type, String routeId, String id) { String name = camelContext.getManagementName() != null ? camelContext.getManagementName() : camelContext.getName(); String answer = namePattern; answer = answer.replaceFirst("##name##", name); answer = answer.replaceFirst("##routeId##", routeId); answer = answer.replaceFirst("##id##", id); answer = answer.replaceFirst("##type##", type); return answer; } @Override protected void doStart() throws Exception { try { messageHistoryService = camelContext.hasService(MetricsMessageHistoryService.class); if (messageHistoryService == null) { messageHistoryService = new MetricsMessageHistoryService(); messageHistoryService.setMetricsRegistry(getMetricsRegistry()); messageHistoryService.setUseJmx(isUseJmx()); messageHistoryService.setJmxDomain(getJmxDomain()); messageHistoryService.setPrettyPrint(isPrettyPrint()); messageHistoryService.setRateUnit(getRateUnit()); messageHistoryService.setDurationUnit(getDurationUnit()); camelContext.addService(messageHistoryService); } } catch (Exception e) { throw ObjectHelper.wrapRuntimeCamelException(e); } // use metrics registry from service if not explicit configured if (metricsRegistry == null) { metricsRegistry = messageHistoryService.getMetricsRegistry(); } ObjectHelper.notNull(metricsRegistry, "metricsRegistry", this); } @Override protected void doStop() throws Exception { // noop } }