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.regionserver;
20  
21  import java.util.Collections;
22  import java.util.Set;
23  import java.util.concurrent.ConcurrentHashMap;
24  import java.util.concurrent.TimeUnit;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.hbase.classification.InterfaceAudience;
29  import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
30  import org.apache.hadoop.hbase.metrics.Interns;
31  import org.apache.hadoop.metrics2.MetricsCollector;
32  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
33  import org.apache.hadoop.metrics2.impl.JmxCacheBuster;
34  import org.apache.hadoop.metrics2.lib.MetricsExecutorImpl;
35  
36  @InterfaceAudience.Private
37  public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
38      implements MetricsRegionAggregateSource {
39  
40    private static final Log LOG = LogFactory.getLog(MetricsRegionAggregateSourceImpl.class);
41  
42    private final MetricsExecutorImpl executor = new MetricsExecutorImpl();
43  
44    private final Set<MetricsRegionSource> regionSources =
45        Collections.newSetFromMap(new ConcurrentHashMap<MetricsRegionSource, Boolean>());
46  
47    public MetricsRegionAggregateSourceImpl() {
48      this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
49    }
50  
51  
52    public MetricsRegionAggregateSourceImpl(String metricsName,
53                                            String metricsDescription,
54                                            String metricsContext,
55                                            String metricsJmxContext) {
56      super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
57  
58      // Every few mins clean the JMX cache.
59      executor.getExecutor().scheduleWithFixedDelay(new Runnable() {
60        public void run() {
61          JmxCacheBuster.clearJmxCache();
62        }
63      }, 5, 5, TimeUnit.MINUTES);
64    }
65  
66    @Override
67    public void register(MetricsRegionSource source) {
68      regionSources.add(source);
69      clearCache();
70    }
71  
72    @Override
73    public void deregister(MetricsRegionSource toRemove) {
74      try {
75        regionSources.remove(toRemove);
76      } catch (Exception e) {
77        // Ignored. If this errors out it means that someone is double
78        // closing the region source and the region is already nulled out.
79        LOG.info(
80            "Error trying to remove " + toRemove + " from " + this.getClass().getSimpleName(),
81            e);
82      }
83      clearCache();
84    }
85  
86    private synchronized void clearCache() {
87      JmxCacheBuster.clearJmxCache();
88    }
89  
90    /**
91     * Yes this is a get function that doesn't return anything.  Thanks Hadoop for breaking all
92     * expectations of java programmers.  Instead of returning anything Hadoop metrics expects
93     * getMetrics to push the metrics into the collector.
94     *
95     * @param collector the collector
96     * @param all       get all the metrics regardless of when they last changed.
97     */
98    @Override
99    public void getMetrics(MetricsCollector collector, boolean all) {
100     MetricsRecordBuilder mrb = collector.addRecord(metricsName);
101 
102     if (regionSources != null) {
103       for (MetricsRegionSource regionMetricSource : regionSources) {
104         if (regionMetricSource instanceof MetricsRegionSourceImpl) {
105           ((MetricsRegionSourceImpl) regionMetricSource).snapshot(mrb, all);
106         }
107       }
108       mrb.addGauge(Interns.info(NUM_REGIONS, NUMBER_OF_REGIONS_DESC), regionSources.size());
109       metricsRegistry.snapshot(mrb, all);
110     }
111   }
112 }