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 */
018
019package org.apache.hadoop.hbase.regionserver;
020
021import java.util.Collections;
022import java.util.Map;
023import java.util.concurrent.ConcurrentHashMap;
024
025import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
026import org.apache.hadoop.metrics2.MetricsCollector;
027import org.apache.hadoop.metrics2.MetricsRecordBuilder;
028import org.apache.hadoop.metrics2.lib.Interns;
029import org.apache.yetus.audience.InterfaceAudience;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033@InterfaceAudience.Private
034public class MetricsUserAggregateSourceImpl extends BaseSourceImpl
035  implements MetricsUserAggregateSource {
036
037  private static final Logger LOG = LoggerFactory.getLogger(MetricsUserAggregateSourceImpl.class);
038
039  private final ConcurrentHashMap<String, MetricsUserSource> userSources =
040      new ConcurrentHashMap<String, MetricsUserSource>();
041
042  public MetricsUserAggregateSourceImpl() {
043    this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
044  }
045
046  public MetricsUserAggregateSourceImpl(String metricsName,
047      String metricsDescription,
048      String metricsContext,
049      String metricsJmxContext) {
050    super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
051  }
052
053  @Override
054  public MetricsUserSource getOrCreateMetricsUser(String user) {
055    MetricsUserSource source = userSources.get(user);
056    if (source != null) {
057      return source;
058    }
059    source = new MetricsUserSourceImpl(user, this);
060    MetricsUserSource prev = userSources.putIfAbsent(user, source);
061
062    if (prev != null) {
063      return prev;
064    } else {
065      // register the new metrics now
066      register(source);
067    }
068    return source;
069  }
070
071  public void register(MetricsUserSource source) {
072    synchronized (this) {
073      source.register();
074    }
075  }
076
077  @Override
078  public void deregister(MetricsUserSource toRemove) {
079    try {
080      synchronized (this) {
081        MetricsUserSource source = userSources.remove(toRemove.getUser());
082        if (source != null) {
083          source.deregister();
084        }
085      }
086    } catch (Exception e) {
087      // Ignored. If this errors out it means that someone is double
088      // closing the user source and the user metrics is already nulled out.
089      LOG.info("Error trying to remove " + toRemove + " from " + getClass().getSimpleName(), e);
090    }
091  }
092
093  @Override
094  public Map<String, MetricsUserSource> getUserSources() {
095    return Collections.unmodifiableMap(userSources);
096  }
097
098  @Override
099  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}