/* * 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 gobblin.metrics.reporter; import java.util.SortedMap; import java.util.concurrent.TimeUnit; import com.codahale.metrics.Counter; import com.codahale.metrics.Gauge; import com.codahale.metrics.Histogram; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricFilter; import com.codahale.metrics.ScheduledReporter; import com.codahale.metrics.Timer; import com.google.common.base.Optional; import gobblin.metrics.MetricContext; /** * A custom {@link com.codahale.metrics.ScheduledReporter} that is aware of the * {@link gobblin.metrics.MetricContext} it is associated to. * * @author Yinan Li */ public abstract class ContextAwareScheduledReporter extends ScheduledReporter { private final MetricContext context; private final Optional<MetricFilter> filter; protected ContextAwareScheduledReporter(MetricContext context, String name, MetricFilter filter, TimeUnit rateUnit, TimeUnit durationUnit) { super(context, name, filter, rateUnit, durationUnit); this.context = context; this.filter = Optional.fromNullable(filter); } @Override public void report() { if (this.filter.isPresent()) { report(this.context.getGauges(this.filter.get()), this.context.getCounters(this.filter.get()), this.context.getHistograms(this.filter.get()), this.context.getMeters(this.filter.get()), this.context.getTimers(this.filter.get())); } else { report(this.context.getGauges(), this.context.getCounters(), this.context.getHistograms(), this.context.getMeters(), this.context.getTimers()); } } @Override public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters, SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers) { reportInContext(this.context, gauges, counters, histograms, meters, timers); } /** * Report all the given metrics in the {@link MetricContext}. * * <p> * Called periodically by the polling thread. Subclasses should report all the given metrics. * </p> * * <p> * The metric names (the keys in the given {@link SortedMap}s) may or may not include the * {@link gobblin.metrics.Tag}s of the {@link MetricContext} depending on if the {@link MetricContext} is * configured to report fully-qualified metric names or not using the method * {@link MetricContext.Builder#reportFullyQualifiedNames(boolean)}. It is up to the * implementation of this method to decide on whether to include the name of the * {@link MetricContext} (given by {@link MetricContext#getName()}) and the {@link gobblin.metrics.Tag}s * of individual {@link gobblin.metrics.ContextAwareMetric}s when reporting them. * </p> * * @param gauges all of the gauges in the {@link MetricContext} * @param counters all of the counters in the {@link MetricContext} * @param histograms all of the histograms in the {@link MetricContext} * @param meters all of the meters in the {@link MetricContext} * @param timers all of the timers in the {@link MetricContext} */ protected abstract void reportInContext(MetricContext context, SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters, SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers); /** * A builder class for {@link ContextAwareScheduledReporter}. * * @param <R> type of a subclass of {@link ContextAwareScheduledReporter} * @param <B> type of a subclass of {@link Builder} */ @SuppressWarnings("unchecked") public abstract static class Builder<R extends ContextAwareScheduledReporter, B extends Builder> { protected final String name; protected MetricFilter filter = MetricFilter.ALL; protected TimeUnit rateUnit = TimeUnit.SECONDS; protected TimeUnit durationUnit = TimeUnit.MILLISECONDS; public Builder(String name) { this.name = name; } /** * Get the name of the {@link ContextAwareScheduledReporter} that is going to be built by this * {@link ContextAwareScheduledReporter.Builder}. * * @return name of the {@link ContextAwareScheduledReporter} that is going to be built */ public String getName() { return this.name; } /** * Build a new {@link ContextAwareScheduledReporter}. * * @param context the {@link MetricContext} of this {@link ContextAwareScheduledReporter} * @return the newly built {@link ContextAwareScheduledReporter} */ public abstract R build(MetricContext context); /** * Only report metrics which match the given filter. * * @param filter a {@link MetricFilter} * @return {@code this} */ public B filter(MetricFilter filter) { this.filter = filter; return (B) this; } /** * Convert rates to the given time unit. * * @param rateUnit a unit of time * @return {@code this} */ public B convertRatesTo(TimeUnit rateUnit) { this.rateUnit = rateUnit; return (B) this; } /** * Convert durations to the given time unit. * * @param durationUnit a unit of time * @return {@code this} */ public B convertDurationsTo(TimeUnit durationUnit) { this.durationUnit = durationUnit; return (B) this; } } }