blob: 85dd7fe727ba30a24bc02bd2bd03442b19b2fe7c [file] [log] [blame]
/*
* 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.drill.exec.metrics;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
import org.apache.drill.exec.util.SystemPropertyUtil;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
import com.codahale.metrics.jmx.JmxReporter;
import com.codahale.metrics.jvm.BufferPoolMetricSet;
import com.codahale.metrics.jvm.CachedThreadStatesGaugeSet;
import com.codahale.metrics.jvm.ClassLoadingGaugeSet;
import com.codahale.metrics.jvm.FileDescriptorRatioGauge;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
public final class DrillMetrics {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillMetrics.class);
public static final boolean METRICS_JMX_OUTPUT_ENABLED =
SystemPropertyUtil.getBoolean("drill.metrics.jmx.enabled", true);
public static final boolean METRICS_LOG_OUTPUT_ENABLED =
SystemPropertyUtil.getBoolean("drill.metrics.log.enabled", false);
public static final int METRICS_LOG_OUTPUT_INTERVAL =
SystemPropertyUtil.getInt("drill.metrics.log.interval", 60);
private static class RegistryHolder {
private static final MetricRegistry REGISTRY;
static {
REGISTRY = new MetricRegistry();
registerSystemMetrics();
getJmxReporter();
getLogReporter();
}
private static void registerSystemMetrics() {
REGISTRY.registerAll(new GarbageCollectorMetricSet());
REGISTRY.registerAll(MetricsCategory.BUFFERPOOL_PREFIX, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
REGISTRY.registerAll(MetricsCategory.MEMORY_PREFIX, new MemoryUsageGaugeSet());
REGISTRY.registerAll(MetricsCategory.THREADS_PREFIX, new ThreadStatesGaugeSet());
REGISTRY.registerAll(MetricsCategory.CACHED_THREADS_PREFIX, new CachedThreadStatesGaugeSet(1, TimeUnit.MINUTES));
REGISTRY.registerAll(MetricsCategory.CLASS_PREFIX, new ClassLoadingGaugeSet());
REGISTRY.registerAll(new CpuGaugeSet());
register("fd.usage", new FileDescriptorRatioGauge());
}
private static JmxReporter getJmxReporter() {
if (METRICS_JMX_OUTPUT_ENABLED) {
JmxReporter reporter = JmxReporter.forRegistry(REGISTRY).build();
reporter.start();
return reporter;
}
return null;
}
private static Slf4jReporter getLogReporter() {
if (METRICS_LOG_OUTPUT_ENABLED) {
Slf4jReporter reporter = Slf4jReporter.forRegistry(REGISTRY)
.outputTo(logger)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
reporter.start(METRICS_LOG_OUTPUT_INTERVAL, TimeUnit.SECONDS);
return reporter;
}
return null;
}
}
/**
* Note: For counters, histograms, meters and timers, use get or create methods on {@link #getRegistry the
* registry} (e.g. {@link MetricRegistry#counter}). For {@link com.codahale.metrics.Gauge gauges} or custom
* metric implementations use this method. The registry does not allow registering multiple metrics with
* the same name, which is a problem when multiple drillbits are started in the same JVM (e.g. unit tests).
*
* @param name metric name
* @param metric metric instance
* @param <T> metric type
*/
public synchronized static <T extends Metric> void register(String name, T metric) {
boolean removed = RegistryHolder.REGISTRY.remove(name);
if (removed) {
logger.warn("Removing old metric since name matched newly registered metric. Metric name: {}", name);
}
RegistryHolder.REGISTRY.register(name, metric);
}
public static MetricRegistry getRegistry() {
return RegistryHolder.REGISTRY;
}
public static void resetMetrics() {
RegistryHolder.REGISTRY.removeMatching(MetricFilter.ALL);
RegistryHolder.registerSystemMetrics();
}
// prevents instantiation
private DrillMetrics() {
}
}