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.concurrent.ConcurrentHashMap;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
28  import org.apache.hadoop.metrics2.MetricsCollector;
29  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
30  import org.apache.hadoop.metrics2.lib.Interns;
31  
32  @InterfaceAudience.Private
33  public class MetricsTableAggregateSourceImpl extends BaseSourceImpl
34  implements MetricsTableAggregateSource {
35  
36    private static final Log LOG = LogFactory.getLog(MetricsTableAggregateSourceImpl.class);
37    private ConcurrentHashMap<String, MetricsTableSource> tableSources = new ConcurrentHashMap<>();
38  
39    public MetricsTableAggregateSourceImpl() {
40      this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
41    }
42  
43    public MetricsTableAggregateSourceImpl(String metricsName,
44        String metricsDescription,
45        String metricsContext,
46        String metricsJmxContext) {
47      super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
48    }
49  
50    private void register(MetricsTableSource source) {
51      synchronized (this) {
52        source.registerMetrics();
53      }
54    }
55  
56    @Override
57    public void deleteTableSource(String table) {
58      try {
59        synchronized (this) {
60          MetricsTableSource source = tableSources.remove(table);
61          if (source != null) {
62            source.close();
63          }
64        }
65      } catch (Exception e) {
66        // Ignored. If this errors out it means that someone is double
67        // closing the user source and the user metrics is already nulled out.
68        LOG.info( "Error trying to remove " + table + " from " + getClass().getSimpleName(), e);
69      }
70    }
71  
72    @Override
73    public MetricsTableSource getOrCreateTableSource(String table,
74        MetricsTableWrapperAggregate wrapper) {
75      MetricsTableSource source = tableSources.get(table);
76      if (source != null) {
77        return source;
78      }
79      source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
80        .createTable(table, wrapper);
81      MetricsTableSource prev = tableSources.putIfAbsent(table, source);
82  
83      if (prev != null) {
84        return prev;
85      } else {
86        // register the new metrics now
87        register(source);
88      }
89      return source;
90    }
91  
92    /**
93     * Yes this is a get function that doesn't return anything.  Thanks Hadoop for breaking all
94     * expectations of java programmers.  Instead of returning anything Hadoop metrics expects
95     * getMetrics to push the metrics into the collector.
96     *
97     * @param collector the collector
98     * @param all       get all the metrics regardless of when they last changed.
99     */
100   @Override
101   public void getMetrics(MetricsCollector collector, boolean all) {
102     MetricsRecordBuilder mrb = collector.addRecord(metricsName);
103 
104     if (tableSources != null) {
105       for (MetricsTableSource tableMetricSource : tableSources.values()) {
106         if (tableMetricSource instanceof MetricsTableSourceImpl) {
107           ((MetricsTableSourceImpl) tableMetricSource).snapshot(mrb, all);
108         }
109       }
110       mrb.addGauge(Interns.info(NUM_TABLES, NUMBER_OF_TABLES_DESC), tableSources.size());
111       metricsRegistry.snapshot(mrb, all);
112     }
113   }
114 }