View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.metrics;
20  
21  import org.apache.hadoop.hbase.classification.InterfaceAudience;
22  import org.apache.hadoop.hbase.metrics.impl.GlobalMetricRegistriesAdapter;
23  import org.apache.hadoop.hbase.metrics.impl.HBaseMetrics2HadoopMetricsAdapter;
24  import org.apache.hadoop.hbase.regionserver.MetricsRegionServerSourceImpl;
25  import org.apache.hadoop.metrics2.MetricsCollector;
26  import org.apache.hadoop.metrics2.MetricsSource;
27  import org.apache.hadoop.metrics2.impl.JmxCacheBuster;
28  import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
29  import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry;
30  import org.apache.hadoop.metrics2.lib.MutableFastCounter;
31  import org.apache.hadoop.metrics2.lib.MutableGaugeLong;
32  import org.apache.hadoop.metrics2.lib.MutableHistogram;
33  import org.apache.hadoop.metrics2.source.JvmMetrics;
34  
35  /**
36   * Hadoop 2 implementation of BaseSource (using metrics2 framework).  It handles registration to
37   * DefaultMetricsSystem and creation of the metrics registry.
38   *
39   * All MetricsSource's in hbase-hadoop2-compat should derive from this class.
40   */
41  @InterfaceAudience.Private
42  public class BaseSourceImpl implements BaseSource, MetricsSource {
43  
44    private static enum DefaultMetricsSystemInitializer {
45      INSTANCE;
46      private boolean inited = false;
47  
48      synchronized void init(String name) {
49        if (inited) return;
50        inited = true;
51        DefaultMetricsSystem.initialize(HBASE_METRICS_SYSTEM_NAME);
52        JvmMetrics.initSingleton(name, "");
53        // initialize hbase-metrics module based metric system as well. GlobalMetricRegistriesSource
54        // initialization depends on the metric system being already initialized, that is why we are
55        // doing it here. Once BaseSourceSourceImpl is removed, we should do the initialization of
56        // these elsewhere.
57        GlobalMetricRegistriesAdapter.init();
58      }
59    }
60  
61    /**
62     * @deprecated Use hbase-metrics/hbase-metrics-api module interfaces for new metrics.
63     * Defining BaseSources for new metric groups (WAL, RPC, etc) is not needed anymore, however,
64     * for existing BaseSource implemetnations, please use the field named "registry" which is a
65     * MetricRegistry instance together with the HBaseMetrics2HadoopMetricsAdapter.
66     */
67    @Deprecated
68    protected final DynamicMetricsRegistry metricsRegistry;
69    protected final String metricsName;
70    protected final String metricsDescription;
71    protected final String metricsContext;
72    protected final String metricsJmxContext;
73  
74    /**
75     * Note that there are at least 4 MetricRegistry definitions in the source code. The first one is
76     * Hadoop Metrics2 MetricRegistry, second one is DynamicMetricsRegistry which is HBase's fork
77     * of the Hadoop metrics2 class. The third one is the dropwizard metrics implementation of
78     * MetricRegistry, and finally a new API abstraction in HBase that is the
79     * o.a.h.h.metrics.MetricRegistry class. This last one is the new way to use metrics within the
80     * HBase code. However, the others are in play because of existing metrics2 based code still
81     * needs to coexists until we get rid of all of our BaseSource and convert them to the new
82     * framework. Until that happens, new metrics can use the new API, but will be collected
83     * through the HBaseMetrics2HadoopMetricsAdapter class.
84     *
85     * BaseSourceImpl has two MetricRegistries. metricRegistry is for hadoop Metrics2 based
86     * metrics, while the registry is for hbase-metrics based metrics.
87     */
88    protected final MetricRegistry registry;
89  
90    /**
91     * The adapter from hbase-metrics module to metrics2. This adepter is the connection between the
92     * Metrics in the MetricRegistry and the Hadoop Metrics2 system. Using this adapter, existing
93     * BaseSource implementations can define new metrics using the hbase-metrics/hbase-metrics-api
94     * module interfaces and still be able to make use of metrics2 sinks (including JMX). Existing
95     * BaseSources should call metricsAdapter.snapshotAllMetrics() in getMetrics() method. See
96     * {@link MetricsRegionServerSourceImpl}.
97     */
98    protected final HBaseMetrics2HadoopMetricsAdapter metricsAdapter;
99  
100   public BaseSourceImpl(
101       String metricsName,
102       String metricsDescription,
103       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   public void init() {
126     this.metricsRegistry.clearMetrics();
127   }
128 
129   /**
130    * Set a single gauge to a value.
131    *
132    * @param gaugeName gauge name
133    * @param value     the new value of the gauge.
134    */
135   public void setGauge(String gaugeName, long value) {
136     MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, value);
137     gaugeInt.set(value);
138   }
139 
140   /**
141    * Add some amount to a gauge.
142    *
143    * @param gaugeName The name of the gauge to increment.
144    * @param delta     The amount to increment the gauge by.
145    */
146   public void incGauge(String gaugeName, long delta) {
147     MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0l);
148     gaugeInt.incr(delta);
149   }
150 
151   /**
152    * Decrease the value of a named gauge.
153    *
154    * @param gaugeName The name of the gauge.
155    * @param delta     the ammount to subtract from a gauge value.
156    */
157   public void decGauge(String gaugeName, long delta) {
158     MutableGaugeLong gaugeInt = metricsRegistry.getGauge(gaugeName, 0l);
159     gaugeInt.decr(delta);
160   }
161 
162   /**
163    * Increment a named counter by some value.
164    *
165    * @param key   the name of the counter
166    * @param delta the ammount to increment
167    */
168   public void incCounters(String key, long delta) {
169     MutableFastCounter counter = metricsRegistry.getCounter(key, 0l);
170     counter.incr(delta);
171 
172   }
173 
174   @Override
175   public void updateHistogram(String name, long value) {
176     MutableHistogram histo = metricsRegistry.getHistogram(name);
177     histo.add(value);
178   }
179 
180   /**
181    * Remove a named gauge.
182    *
183    * @param key
184    */
185   public void removeMetric(String key) {
186     metricsRegistry.removeMetric(key);
187     JmxCacheBuster.clearJmxCache();
188   }
189 
190   @Override
191   public void getMetrics(MetricsCollector metricsCollector, boolean all) {
192     metricsRegistry.snapshot(metricsCollector.addRecord(metricsRegistry.info()), all);
193   }
194 
195   public DynamicMetricsRegistry getMetricsRegistry() {
196     return metricsRegistry;
197   }
198 
199   public String getMetricsContext() {
200     return metricsContext;
201   }
202 
203   public String getMetricsDescription() {
204     return metricsDescription;
205   }
206 
207   public String getMetricsJmxContext() {
208     return metricsJmxContext;
209   }
210 
211   public String getMetricsName() {
212     return metricsName;
213   }
214 
215   @Override
216   public MetricRegistryInfo getMetricRegistryInfo() {
217     return new MetricRegistryInfo(getMetricsName(), getMetricsDescription(),
218       getMetricsContext(), getMetricsJmxContext(), true);
219   }
220 
221 }