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.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
27  import org.apache.hadoop.metrics2.MetricsCollector;
28  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
29  import org.apache.hadoop.metrics2.lib.Interns;
30  
31  @InterfaceAudience.Private
32  public class MetricsUserAggregateSourceImpl extends BaseSourceImpl
33    implements MetricsUserAggregateSource {
34  
35    private static final Log LOG = LogFactory.getLog(MetricsUserAggregateSourceImpl.class);
36  
37    private final ConcurrentHashMap<String, MetricsUserSource> userSources =
38        new ConcurrentHashMap<String, MetricsUserSource>();
39  
40    public MetricsUserAggregateSourceImpl() {
41      this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
42    }
43  
44    public MetricsUserAggregateSourceImpl(String metricsName,
45        String metricsDescription,
46        String metricsContext,
47        String metricsJmxContext) {
48      super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
49    }
50  
51    @Override
52    public MetricsUserSource getOrCreateMetricsUser(String user) {
53      MetricsUserSource source = userSources.get(user);
54      if (source != null) {
55        return source;
56      }
57      source = new MetricsUserSourceImpl(user, this);
58      MetricsUserSource prev = userSources.putIfAbsent(user, source);
59  
60      if (prev != null) {
61        return prev;
62      } else {
63        // register the new metrics now
64        register(source);
65      }
66      return source;
67    }
68  
69    public void register(MetricsUserSource source) {
70      synchronized (this) {
71        source.register();
72      }
73    }
74  
75    public void deregister(MetricsUserSource toRemove) {
76      /*
77       * We do not deregister per-user level metrics for now, so this function is not used. The user
78       * can go away and come back hours or days later, but we still would like to keep context for
79       * the user to calculate the counters and rates. Users are usually static in a cluster and
80       * there are not thousands of them, so it should be fine to not do the cleanup.
81       *
82       * Since we are not removing metrics, JmxCacheBuster is also not called periodically.
83       */
84      try {
85        synchronized (this) {
86          MetricsUserSource source = userSources.remove(toRemove.getUser());
87          if (source != null) {
88            source.deregister();
89          }
90        }
91      } catch (Exception e) {
92        // Ignored. If this errors out it means that someone is double
93        // closing the user source and the user metrics is already nulled out.
94        LOG.info( "Error trying to remove " + toRemove + " from " + getClass().getSimpleName(), e);
95      }
96    }
97  
98    @Override
99    public void getMetrics(MetricsCollector collector, boolean all) {
100     MetricsRecordBuilder mrb = collector.addRecord(metricsName);
101 
102     if (userSources != null) {
103       for (MetricsUserSource userMetricSource : userSources.values()) {
104         if (userMetricSource instanceof MetricsUserSourceImpl) {
105           ((MetricsUserSourceImpl) userMetricSource).snapshot(mrb, all);
106         }
107       }
108       mrb.addGauge(Interns.info(NUM_USERS, NUMBER_OF_USERS_DESC), userSources.size());
109       metricsRegistry.snapshot(mrb, all);
110     }
111   }
112 }