diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricWriter.java new file mode 100644 index 0000000000..939d2e4b1d --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricWriter.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed 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.springframework.boot.actuate.metrics.writer; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +import org.springframework.boot.actuate.metrics.Metric; +import org.springframework.boot.actuate.metrics.dropwizard.DropwizardMetricServices; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; + +/** + * A {@link MetricWriter} that send data to a Codahale {@link MetricRegistry} based on a + * naming convention: + * + * + * + * @author Dave Syer + * + * @deprecated Use {@link DropwizardMetricServices} instead + */ +@Deprecated +public class DropwizardMetricWriter implements MetricWriter { + + private final MetricRegistry registry; + + private final ConcurrentMap gaugeLocks = new ConcurrentHashMap(); + + /** + * Create a new {@link DropwizardMetricWriter} instance. + * @param registry the underlying metric registry + */ + public DropwizardMetricWriter(MetricRegistry registry) { + this.registry = registry; + } + + @Override + public void increment(Delta delta) { + String name = delta.getName(); + long value = delta.getValue().longValue(); + if (name.startsWith("meter")) { + Meter meter = this.registry.meter(name); + meter.mark(value); + } + else { + Counter counter = this.registry.counter(name); + counter.inc(value); + } + } + + @Override + public void set(Metric value) { + String name = value.getName(); + if (name.startsWith("histogram")) { + long longValue = value.getValue().longValue(); + Histogram metric = this.registry.histogram(name); + metric.update(longValue); + } + else if (name.startsWith("timer")) { + long longValue = value.getValue().longValue(); + Timer metric = this.registry.timer(name); + metric.update(longValue, TimeUnit.MILLISECONDS); + } + else { + final double gauge = value.getValue().doubleValue(); + // Ensure we synchronize to avoid another thread pre-empting this thread after + // remove causing an error in CodaHale metrics + // NOTE: CodaHale provides no way to do this atomically + synchronized (getGuageLock(name)) { + this.registry.remove(name); + this.registry.register(name, new SimpleGauge(gauge)); + } + } + } + + private Object getGuageLock(String name) { + Object lock = this.gaugeLocks.get(name); + if (lock == null) { + Object newLock = new Object(); + lock = this.gaugeLocks.putIfAbsent(name, newLock); + lock = (lock == null ? newLock : lock); + } + return lock; + } + + @Override + public void reset(String metricName) { + this.registry.remove(metricName); + } + + /** + * Simple {@link Gauge} implementation to {@literal double} value. + */ + private static class SimpleGauge implements Gauge { + + private final double value; + + private SimpleGauge(double value) { + this.value = value; + } + + @Override + public Double getValue() { + return this.value; + } + } + +}