View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.hadoop.hbase.master;
18  
19  import java.util.Map;
20  import java.util.Map.Entry;
21  
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
24  import org.apache.hadoop.metrics2.MetricHistogram;
25  import org.apache.hadoop.metrics2.MetricsCollector;
26  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
27  import org.apache.hadoop.metrics2.lib.Interns;
28  import org.apache.hadoop.metrics2.lib.MutableGaugeLong;
29  
30  /**
31   * Implementation of {@link MetricsMasterQuotaSource} which writes the values passed in via the
32   * interface to the metrics backend.
33   */
34  @InterfaceAudience.Private
35  public class MetricsMasterQuotaSourceImpl extends BaseSourceImpl implements MetricsMasterQuotaSource {
36    private final MetricsMasterWrapper wrapper;
37    private final MutableGaugeLong spaceQuotasGauge;
38    private final MutableGaugeLong tablesViolatingQuotasGauge;
39    private final MutableGaugeLong namespacesViolatingQuotasGauge;
40    private final MutableGaugeLong regionSpaceReportsGauge;
41    private final MetricHistogram quotaObserverTimeHisto;
42  
43    public MetricsMasterQuotaSourceImpl(MetricsMasterWrapper wrapper) {
44      this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT, wrapper);
45    }
46  
47    public MetricsMasterQuotaSourceImpl(
48        String metricsName, String metricsDescription, String metricsContext,
49        String metricsJmxContext, MetricsMasterWrapper wrapper) {
50      super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
51      this.wrapper = wrapper;
52  
53      spaceQuotasGauge = getMetricsRegistry().newGauge(
54          NUM_SPACE_QUOTAS_NAME, NUM_SPACE_QUOTAS_DESC, 0L);
55      tablesViolatingQuotasGauge = getMetricsRegistry().newGauge(
56          NUM_TABLES_QUOTA_VIOLATIONS_NAME, NUM_TABLES_QUOTA_VIOLATIONS_DESC, 0L);
57      namespacesViolatingQuotasGauge = getMetricsRegistry().newGauge(
58          NUM_NS_QUOTA_VIOLATIONS_NAME, NUM_NS_QUOTA_VIOLATIONS_DESC, 0L);
59      regionSpaceReportsGauge = getMetricsRegistry().newGauge(
60          NUM_REGION_SIZE_REPORTS_NAME, NUM_REGION_SIZE_REPORTS_DESC, 0L);
61  
62      quotaObserverTimeHisto = getMetricsRegistry().newTimeHistogram(
63          QUOTA_OBSERVER_CHORE_TIME_NAME, QUOTA_OBSERVER_CHORE_TIME_DESC);
64    }
65  
66    @Override
67    public void updateNumSpaceQuotas(long numSpaceQuotas) {
68      spaceQuotasGauge.set(numSpaceQuotas);
69    }
70  
71    @Override
72    public void updateNumTablesInSpaceQuotaViolation(long numTablesInViolation) {
73      tablesViolatingQuotasGauge.set(numTablesInViolation);
74    }
75  
76    @Override
77    public void updateNumNamespacesInSpaceQuotaViolation(long numNamespacesInViolation) {
78      namespacesViolatingQuotasGauge.set(numNamespacesInViolation);
79    }
80  
81    @Override
82    public void updateNumCurrentSpaceQuotaRegionSizeReports(long numCurrentRegionSizeReports) {
83      regionSpaceReportsGauge.set(numCurrentRegionSizeReports);
84    }
85  
86    @Override
87    public void incrementSpaceQuotaObserverChoreTime(long time) {
88      quotaObserverTimeHisto.add(time);
89    }
90  
91    @Override
92    public void getMetrics(MetricsCollector metricsCollector, boolean all) {
93      MetricsRecordBuilder record = metricsCollector.addRecord(metricsRegistry.info());
94      if (wrapper != null) {
95        // Summarize the tables
96        Map<String,Entry<Long,Long>> tableUsages = wrapper.getTableSpaceUtilization();
97        String tableSummary = "[]";
98        if (tableUsages != null && !tableUsages.isEmpty()) {
99          tableSummary = generateJsonQuotaSummary(tableUsages.entrySet(), "table");
100       }
101       record.tag(Interns.info(TABLE_QUOTA_USAGE_NAME, TABLE_QUOTA_USAGE_DESC), tableSummary);
102 
103       // Summarize the namespaces
104       String nsSummary = "[]";
105       Map<String,Entry<Long,Long>> namespaceUsages = wrapper.getNamespaceSpaceUtilization();
106       if (namespaceUsages != null && !namespaceUsages.isEmpty()) {
107         nsSummary = generateJsonQuotaSummary(namespaceUsages.entrySet(), "namespace");
108       }
109       record.tag(Interns.info(NS_QUOTA_USAGE_NAME, NS_QUOTA_USAGE_DESC), nsSummary);
110     }
111     metricsRegistry.snapshot(record, all);
112   }
113 
114   /**
115    * Summarizes the usage and limit for many targets (table or namespace) into JSON.
116    */
117   private String generateJsonQuotaSummary(
118       Iterable<Entry<String,Entry<Long,Long>>> data, String target) {
119     StringBuilder sb = new StringBuilder();
120     for (Entry<String,Entry<Long,Long>> tableUsage : data) {
121       String tableName = tableUsage.getKey();
122       long usage = tableUsage.getValue().getKey();
123       long limit = tableUsage.getValue().getValue();
124       if (sb.length() > 0) {
125         sb.append(", ");
126       }
127       sb.append("{").append(target).append("=").append(tableName).append(", usage=").append(usage)
128           .append(", limit=").append(limit).append("}");
129     }
130     sb.insert(0, "[").append("]");
131     return sb.toString();
132   }
133 }