001/*
002 * (C) Copyright 2020 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bdelbosc
018 */
019package org.nuxeo.runtime.metrics.reporter.patch;
020
021import java.util.Collections;
022import java.util.Map;
023import java.util.SortedMap;
024import java.util.TreeMap;
025import java.util.concurrent.TimeUnit;
026
027import org.nuxeo.runtime.metrics.MetricsConfigurationDescriptor;
028
029import io.dropwizard.metrics5.Counter;
030import io.dropwizard.metrics5.Gauge;
031import io.dropwizard.metrics5.Histogram;
032import io.dropwizard.metrics5.Meter;
033import io.dropwizard.metrics5.Metric;
034import io.dropwizard.metrics5.MetricFilter;
035import io.dropwizard.metrics5.MetricName;
036import io.dropwizard.metrics5.MetricRegistry;
037import io.dropwizard.metrics5.ScheduledReporter;
038import io.dropwizard.metrics5.Timer;
039import io.dropwizard.metrics5.graphite.GraphiteReporter;
040
041/**
042 * A Graphite Reporter that handles metric name with tagging. A metric "foo.bar.baz" with tag "bar=qux" is rewritten as
043 * "foo.bar.qux.baz".
044 *
045 * @since 11.1
046 */
047public class NuxeoGraphiteReporter extends ScheduledReporter {
048
049    protected GraphiteReporter reporter;
050
051    public NuxeoGraphiteReporter(MetricRegistry registry, MetricFilter filter, GraphiteReporter reporter) {
052        super(registry, "graphite-reporter", filter, TimeUnit.SECONDS,
053                TimeUnit.SECONDS);
054        this.reporter = reporter;
055    }
056
057    @Override
058    public void report(SortedMap<MetricName, Gauge> gauges, SortedMap<MetricName, Counter> counters,
059            SortedMap<MetricName, Histogram> histograms, SortedMap<MetricName, Meter> meters,
060            SortedMap<MetricName, Timer> timers) {
061        reporter.report(graphiteMetrics(gauges), graphiteMetrics(counters), graphiteMetrics(histograms),
062                graphiteMetrics(meters), graphiteMetrics(timers));
063    }
064
065    protected <T extends Metric> SortedMap<MetricName, T> graphiteMetrics(SortedMap<MetricName, T> metrics) {
066        final SortedMap<MetricName, T> nuxeoMetrics = new TreeMap<>();
067        for (Map.Entry<MetricName, T> entry : metrics.entrySet()) {
068            MetricName name = entry.getKey();
069            if (name.getTags().isEmpty()) {
070                nuxeoMetrics.put(name, entry.getValue());
071            } else {
072                nuxeoMetrics.put(convertName(name), entry.getValue());
073            }
074        }
075        return Collections.unmodifiableSortedMap(nuxeoMetrics);
076    }
077
078    protected MetricName convertName(MetricName name) {
079        String graphiteName = MetricsConfigurationDescriptor.expandName(name);
080        return MetricName.build(graphiteName);
081    }
082
083    @Override
084    public void stop() {
085        reporter.stop();
086        reporter = null;
087        super.stop();
088    }
089}