| /* |
| * 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() { |
| } |
| } |