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 */ 018 019package org.apache.hadoop.hbase.metrics; 020 021import org.apache.hadoop.hbase.metrics.impl.GlobalMetricRegistriesAdapter; 022import org.apache.hadoop.hbase.metrics.impl.HBaseMetrics2HadoopMetricsAdapter; 023import org.apache.hadoop.hbase.regionserver.MetricsRegionServerSourceImpl; 024import org.apache.hadoop.metrics2.MetricsCollector; 025import org.apache.hadoop.metrics2.MetricsSource; 026import org.apache.hadoop.metrics2.impl.JmxCacheBuster; 027import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; 028import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry; 029import org.apache.hadoop.metrics2.lib.MutableFastCounter; 030import org.apache.hadoop.metrics2.lib.MutableGaugeLong; 031import org.apache.hadoop.metrics2.lib.MutableHistogram; 032import org.apache.hadoop.metrics2.source.JvmMetrics; 033import org.apache.yetus.audience.InterfaceAudience; 034 035/** 036 * Hadoop 2 implementation of BaseSource (using metrics2 framework). It handles registration to 037 * DefaultMetricsSystem and creation of the metrics registry. 038 * 039 * All MetricsSource's in hbase-hadoop2-compat should derive from this class. 040 */ 041@InterfaceAudience.Private 042public class BaseSourceImpl implements BaseSource, MetricsSource { 043 044 private static enum DefaultMetricsSystemInitializer { 045 INSTANCE; 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. 066 * Defining BaseSources for new metric groups (WAL, RPC, etc) is not needed anymore, 067 * however, for existing {@link BaseSource} implementations, please use the field 068 * named "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 081 * of 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 085 * needs to coexists until we get rid of all of our BaseSource and convert them to the new 086 * framework. Until that happens, new metrics can use the new API, but will be collected 087 * through the HBaseMetrics2HadoopMetricsAdapter class. 088 * 089 * BaseSourceImpl has two MetricRegistries. metricRegistry is for hadoop Metrics2 based 090 * metrics, while the registry is for hbase-metrics based metrics. 091 */ 092 protected final MetricRegistry registry; 093 094 /** 095 * The adapter from hbase-metrics module to metrics2. This adepter is the connection between the 096 * Metrics in the MetricRegistry and the Hadoop Metrics2 system. Using this adapter, existing 097 * BaseSource implementations can define new metrics using the hbase-metrics/hbase-metrics-api 098 * module interfaces and still be able to make use of metrics2 sinks (including JMX). Existing 099 * BaseSources should call metricsAdapter.snapshotAllMetrics() in getMetrics() method. See 100 * {@link MetricsRegionServerSourceImpl}. 101 */ 102 protected final HBaseMetrics2HadoopMetricsAdapter metricsAdapter; 103 104 public BaseSourceImpl( 105 String metricsName, 106 String metricsDescription, 107 String metricsContext, 108 String metricsJmxContext) { 109 110 this.metricsName = metricsName; 111 this.metricsDescription = metricsDescription; 112 this.metricsContext = metricsContext; 113 this.metricsJmxContext = metricsJmxContext; 114 115 metricsRegistry = new DynamicMetricsRegistry(metricsName).setContext(metricsContext); 116 DefaultMetricsSystemInitializer.INSTANCE.init(metricsName); 117 118 //Register this instance. 119 DefaultMetricsSystem.instance().register(metricsJmxContext, metricsDescription, this); 120 121 // hbase-metrics module based metrics are registered in the hbase MetricsRegistry. 122 registry = MetricRegistries.global().create(this.getMetricRegistryInfo()); 123 metricsAdapter = new HBaseMetrics2HadoopMetricsAdapter(); 124 125 init(); 126 127 } 128 129 public void init() { 130 this.metricsRegistry.clearMetrics(); 131 } 132 133 /** 134 * Set a single gauge to a value. 135 * 136 * @param gaugeName gauge name 137 * @param value the new value of the gauge. 138 */ 139 public void setGauge(String gaugeName, long value) { 140 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, value); 141 gaugeInt.set(value); 142 } 143 144 /** 145 * Add some amount to a gauge. 146 * 147 * @param gaugeName The name of the gauge to increment. 148 * @param delta The amount to increment the gauge by. 149 */ 150 public void incGauge(String gaugeName, long delta) { 151 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 152 gaugeInt.incr(delta); 153 } 154 155 /** 156 * Decrease the value of a named gauge. 157 * 158 * @param gaugeName The name of the gauge. 159 * @param delta the ammount to subtract from a gauge value. 160 */ 161 public void decGauge(String gaugeName, long delta) { 162 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 163 gaugeInt.decr(delta); 164 } 165 166 /** 167 * Increment a named counter by some value. 168 * 169 * @param key the name of the counter 170 * @param delta the ammount to increment 171 */ 172 public void incCounters(String key, long delta) { 173 MutableFastCounter counter = metricsRegistry.getCounter(key, 0L); 174 counter.incr(delta); 175 176 } 177 178 @Override 179 public void updateHistogram(String name, long value) { 180 MutableHistogram histo = metricsRegistry.getHistogram(name); 181 histo.add(value); 182 } 183 184 /** 185 * Remove a named gauge. 186 * 187 * @param key the key of the gauge to remove 188 */ 189 public void removeMetric(String key) { 190 metricsRegistry.removeMetric(key); 191 JmxCacheBuster.clearJmxCache(); 192 } 193 194 @Override 195 public void getMetrics(MetricsCollector metricsCollector, boolean all) { 196 metricsRegistry.snapshot(metricsCollector.addRecord(metricsRegistry.info()), all); 197 } 198 199 public DynamicMetricsRegistry getMetricsRegistry() { 200 return metricsRegistry; 201 } 202 203 public String getMetricsContext() { 204 return metricsContext; 205 } 206 207 public String getMetricsDescription() { 208 return metricsDescription; 209 } 210 211 public String getMetricsJmxContext() { 212 return metricsJmxContext; 213 } 214 215 public String getMetricsName() { 216 return metricsName; 217 } 218 219}