001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.metrics; 019 020import org.apache.hadoop.hbase.metrics.impl.GlobalMetricRegistriesAdapter; 021import org.apache.hadoop.hbase.metrics.impl.HBaseMetrics2HadoopMetricsAdapter; 022import org.apache.hadoop.hbase.regionserver.MetricsRegionServerSourceImpl; 023import org.apache.hadoop.metrics2.MetricsCollector; 024import org.apache.hadoop.metrics2.MetricsSource; 025import org.apache.hadoop.metrics2.impl.JmxCacheBuster; 026import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; 027import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry; 028import org.apache.hadoop.metrics2.lib.MutableFastCounter; 029import org.apache.hadoop.metrics2.lib.MutableGaugeLong; 030import org.apache.hadoop.metrics2.lib.MutableHistogram; 031import org.apache.hadoop.metrics2.source.JvmMetrics; 032import org.apache.yetus.audience.InterfaceAudience; 033 034/** 035 * Hadoop 2 implementation of BaseSource (using metrics2 framework). It handles registration to 036 * DefaultMetricsSystem and creation of the metrics registry. All MetricsSource's in 037 * hbase-hadoop2-compat should derive from this class. 038 */ 039@InterfaceAudience.Private 040public class BaseSourceImpl implements BaseSource, MetricsSource { 041 042 @SuppressWarnings("ImmutableEnumChecker") 043 private static enum DefaultMetricsSystemInitializer { 044 INSTANCE; 045 046 private boolean inited = false; 047 048 synchronized void init(String name) { 049 if (inited) { 050 return; 051 } 052 053 inited = true; 054 DefaultMetricsSystem.initialize(HBASE_METRICS_SYSTEM_NAME); 055 JvmMetrics.initSingleton(name, ""); 056 // initialize hbase-metrics module based metric system as well. GlobalMetricRegistriesSource 057 // initialization depends on the metric system being already initialized, that is why we are 058 // doing it here. Once BaseSourceSourceImpl is removed, we should do the initialization of 059 // these elsewhere. 060 GlobalMetricRegistriesAdapter.init(); 061 } 062 } 063 064 /** 065 * @deprecated Use hbase-metrics/hbase-metrics-api module interfaces for new metrics. Defining 066 * BaseSources for new metric groups (WAL, RPC, etc) is not needed anymore, however, 067 * for existing {@link BaseSource} implementations, please use the field named 068 * "registry" which is a {@link MetricRegistry} instance together with the 069 * {@link HBaseMetrics2HadoopMetricsAdapter}. 070 */ 071 @Deprecated 072 protected final DynamicMetricsRegistry metricsRegistry; 073 protected final String metricsName; 074 protected final String metricsDescription; 075 protected final String metricsContext; 076 protected final String metricsJmxContext; 077 078 /** 079 * Note that there are at least 4 MetricRegistry definitions in the source code. The first one is 080 * Hadoop Metrics2 MetricRegistry, second one is DynamicMetricsRegistry which is HBase's fork of 081 * the Hadoop metrics2 class. The third one is the dropwizard metrics implementation of 082 * MetricRegistry, and finally a new API abstraction in HBase that is the 083 * o.a.h.h.metrics.MetricRegistry class. This last one is the new way to use metrics within the 084 * HBase code. However, the others are in play because of existing metrics2 based code still needs 085 * to coexists until we get rid of all of our BaseSource and convert them to the new framework. 086 * Until that happens, new metrics can use the new API, but will be collected through the 087 * HBaseMetrics2HadoopMetricsAdapter class. BaseSourceImpl has two MetricRegistries. 088 * metricRegistry is for hadoop Metrics2 based metrics, while the registry is for hbase-metrics 089 * based metrics. 090 */ 091 protected final MetricRegistry registry; 092 093 /** 094 * The adapter from hbase-metrics module to metrics2. This adepter is the connection between the 095 * Metrics in the MetricRegistry and the Hadoop Metrics2 system. Using this adapter, existing 096 * BaseSource implementations can define new metrics using the hbase-metrics/hbase-metrics-api 097 * module interfaces and still be able to make use of metrics2 sinks (including JMX). Existing 098 * BaseSources should call metricsAdapter.snapshotAllMetrics() in getMetrics() method. See 099 * {@link MetricsRegionServerSourceImpl}. 100 */ 101 protected final HBaseMetrics2HadoopMetricsAdapter metricsAdapter; 102 103 public BaseSourceImpl(String metricsName, String metricsDescription, String metricsContext, 104 String metricsJmxContext) { 105 106 this.metricsName = metricsName; 107 this.metricsDescription = metricsDescription; 108 this.metricsContext = metricsContext; 109 this.metricsJmxContext = metricsJmxContext; 110 111 metricsRegistry = new DynamicMetricsRegistry(metricsName).setContext(metricsContext); 112 DefaultMetricsSystemInitializer.INSTANCE.init(metricsName); 113 114 // Register this instance. 115 DefaultMetricsSystem.instance().register(metricsJmxContext, metricsDescription, this); 116 117 // hbase-metrics module based metrics are registered in the hbase MetricsRegistry. 118 registry = MetricRegistries.global().create(this.getMetricRegistryInfo()); 119 metricsAdapter = new HBaseMetrics2HadoopMetricsAdapter(); 120 121 init(); 122 123 } 124 125 @Override 126 public void init() { 127 this.metricsRegistry.clearMetrics(); 128 } 129 130 /** 131 * Set a single gauge to a value. 132 * @param gaugeName gauge name 133 * @param value the new value of the gauge. 134 */ 135 @Override 136 public void setGauge(String gaugeName, long value) { 137 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, value); 138 gaugeInt.set(value); 139 } 140 141 /** 142 * Add some amount to a gauge. 143 * @param gaugeName The name of the gauge to increment. 144 * @param delta The amount to increment the gauge by. 145 */ 146 @Override 147 public void incGauge(String gaugeName, long delta) { 148 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 149 gaugeInt.incr(delta); 150 } 151 152 /** 153 * Decrease the value of a named gauge. 154 * @param gaugeName The name of the gauge. 155 * @param delta the ammount to subtract from a gauge value. 156 */ 157 @Override 158 public void decGauge(String gaugeName, long delta) { 159 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 160 gaugeInt.decr(delta); 161 } 162 163 /** 164 * Increment a named counter by some value. 165 * @param key the name of the counter 166 * @param delta the ammount to increment 167 */ 168 @Override 169 public void incCounters(String key, long delta) { 170 MutableFastCounter counter = metricsRegistry.getCounter(key, 0L); 171 counter.incr(delta); 172 173 } 174 175 @Override 176 public void updateHistogram(String name, long value) { 177 MutableHistogram histo = metricsRegistry.getHistogram(name); 178 histo.add(value); 179 } 180 181 /** 182 * Remove a named gauge. 183 * @param key the key of the gauge to remove 184 */ 185 @Override 186 public void removeMetric(String key) { 187 metricsRegistry.removeMetric(key); 188 JmxCacheBuster.clearJmxCache(); 189 } 190 191 @Override 192 public void getMetrics(MetricsCollector metricsCollector, boolean all) { 193 metricsRegistry.snapshot(metricsCollector.addRecord(metricsRegistry.info()), all); 194 } 195 196 public DynamicMetricsRegistry getMetricsRegistry() { 197 return metricsRegistry; 198 } 199 200 @Override 201 public String getMetricsContext() { 202 return metricsContext; 203 } 204 205 @Override 206 public String getMetricsDescription() { 207 return metricsDescription; 208 } 209 210 @Override 211 public String getMetricsJmxContext() { 212 return metricsJmxContext; 213 } 214 215 @Override 216 public String getMetricsName() { 217 return metricsName; 218 } 219 220}