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 private static enum DefaultMetricsSystemInitializer { 043 INSTANCE; 044 045 private boolean inited = false; 046 047 synchronized void init(String name) { 048 if (inited) { 049 return; 050 } 051 052 inited = true; 053 DefaultMetricsSystem.initialize(HBASE_METRICS_SYSTEM_NAME); 054 JvmMetrics.initSingleton(name, ""); 055 // initialize hbase-metrics module based metric system as well. GlobalMetricRegistriesSource 056 // initialization depends on the metric system being already initialized, that is why we are 057 // doing it here. Once BaseSourceSourceImpl is removed, we should do the initialization of 058 // these elsewhere. 059 GlobalMetricRegistriesAdapter.init(); 060 } 061 } 062 063 /** 064 * @deprecated Use hbase-metrics/hbase-metrics-api module interfaces for new metrics. Defining 065 * BaseSources for new metric groups (WAL, RPC, etc) is not needed anymore, however, 066 * for existing {@link BaseSource} implementations, please use the field named 067 * "registry" which is a {@link MetricRegistry} instance together with the 068 * {@link HBaseMetrics2HadoopMetricsAdapter}. 069 */ 070 @Deprecated 071 protected final DynamicMetricsRegistry metricsRegistry; 072 protected final String metricsName; 073 protected final String metricsDescription; 074 protected final String metricsContext; 075 protected final String metricsJmxContext; 076 077 /** 078 * Note that there are at least 4 MetricRegistry definitions in the source code. The first one is 079 * Hadoop Metrics2 MetricRegistry, second one is DynamicMetricsRegistry which is HBase's fork of 080 * the Hadoop metrics2 class. The third one is the dropwizard metrics implementation of 081 * MetricRegistry, and finally a new API abstraction in HBase that is the 082 * o.a.h.h.metrics.MetricRegistry class. This last one is the new way to use metrics within the 083 * HBase code. However, the others are in play because of existing metrics2 based code still needs 084 * to coexists until we get rid of all of our BaseSource and convert them to the new framework. 085 * Until that happens, new metrics can use the new API, but will be collected through the 086 * HBaseMetrics2HadoopMetricsAdapter class. BaseSourceImpl has two MetricRegistries. 087 * metricRegistry is for hadoop Metrics2 based metrics, while the registry is for hbase-metrics 088 * based metrics. 089 */ 090 protected final MetricRegistry registry; 091 092 /** 093 * The adapter from hbase-metrics module to metrics2. This adepter is the connection between the 094 * Metrics in the MetricRegistry and the Hadoop Metrics2 system. Using this adapter, existing 095 * BaseSource implementations can define new metrics using the hbase-metrics/hbase-metrics-api 096 * module interfaces and still be able to make use of metrics2 sinks (including JMX). Existing 097 * BaseSources should call metricsAdapter.snapshotAllMetrics() in getMetrics() method. See 098 * {@link MetricsRegionServerSourceImpl}. 099 */ 100 protected final HBaseMetrics2HadoopMetricsAdapter metricsAdapter; 101 102 public BaseSourceImpl(String metricsName, String metricsDescription, String metricsContext, 103 String metricsJmxContext) { 104 105 this.metricsName = metricsName; 106 this.metricsDescription = metricsDescription; 107 this.metricsContext = metricsContext; 108 this.metricsJmxContext = metricsJmxContext; 109 110 metricsRegistry = new DynamicMetricsRegistry(metricsName).setContext(metricsContext); 111 DefaultMetricsSystemInitializer.INSTANCE.init(metricsName); 112 113 // Register this instance. 114 DefaultMetricsSystem.instance().register(metricsJmxContext, metricsDescription, this); 115 116 // hbase-metrics module based metrics are registered in the hbase MetricsRegistry. 117 registry = MetricRegistries.global().create(this.getMetricRegistryInfo()); 118 metricsAdapter = new HBaseMetrics2HadoopMetricsAdapter(); 119 120 init(); 121 122 } 123 124 public void init() { 125 this.metricsRegistry.clearMetrics(); 126 } 127 128 /** 129 * Set a single gauge to a value. 130 * @param gaugeName gauge name 131 * @param value the new value of the gauge. 132 */ 133 public void setGauge(String gaugeName, long value) { 134 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, value); 135 gaugeInt.set(value); 136 } 137 138 /** 139 * Add some amount to a gauge. 140 * @param gaugeName The name of the gauge to increment. 141 * @param delta The amount to increment the gauge by. 142 */ 143 public void incGauge(String gaugeName, long delta) { 144 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 145 gaugeInt.incr(delta); 146 } 147 148 /** 149 * Decrease the value of a named gauge. 150 * @param gaugeName The name of the gauge. 151 * @param delta the ammount to subtract from a gauge value. 152 */ 153 public void decGauge(String gaugeName, long delta) { 154 MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0L); 155 gaugeInt.decr(delta); 156 } 157 158 /** 159 * Increment a named counter by some value. 160 * @param key the name of the counter 161 * @param delta the ammount to increment 162 */ 163 public void incCounters(String key, long delta) { 164 MutableFastCounter counter = metricsRegistry.getCounter(key, 0L); 165 counter.incr(delta); 166 167 } 168 169 @Override 170 public void updateHistogram(String name, long value) { 171 MutableHistogram histo = metricsRegistry.getHistogram(name); 172 histo.add(value); 173 } 174 175 /** 176 * Remove a named gauge. 177 * @param key the key of the gauge to remove 178 */ 179 public void removeMetric(String key) { 180 metricsRegistry.removeMetric(key); 181 JmxCacheBuster.clearJmxCache(); 182 } 183 184 @Override 185 public void getMetrics(MetricsCollector metricsCollector, boolean all) { 186 metricsRegistry.snapshot(metricsCollector.addRecord(metricsRegistry.info()), all); 187 } 188 189 public DynamicMetricsRegistry getMetricsRegistry() { 190 return metricsRegistry; 191 } 192 193 public String getMetricsContext() { 194 return metricsContext; 195 } 196 197 public String getMetricsDescription() { 198 return metricsDescription; 199 } 200 201 public String getMetricsJmxContext() { 202 return metricsJmxContext; 203 } 204 205 public String getMetricsName() { 206 return metricsName; 207 } 208 209}