001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to you under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.hadoop.hbase.regionserver;
018
019import java.util.HashMap;
020import org.apache.hadoop.hbase.TableName;
021import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
022import org.apache.hadoop.metrics2.MetricHistogram;
023import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry;
024import org.apache.yetus.audience.InterfaceAudience;
025
026import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
027
028/**
029 * Implementation of {@link MetricsTableLatencies} to track latencies for one table in a
030 * RegionServer.
031 */
032@InterfaceAudience.Private
033public class MetricsTableLatenciesImpl extends BaseSourceImpl implements MetricsTableLatencies {
034
035  private final HashMap<TableName,TableHistograms> histogramsByTable = new HashMap<>();
036
037  @VisibleForTesting
038  public static class TableHistograms {
039    final MetricHistogram getTimeHisto;
040    final MetricHistogram incrementTimeHisto;
041    final MetricHistogram appendTimeHisto;
042    final MetricHistogram putTimeHisto;
043    final MetricHistogram putBatchTimeHisto;
044    final MetricHistogram deleteTimeHisto;
045    final MetricHistogram deleteBatchTimeHisto;
046    final MetricHistogram scanTimeHisto;
047    final MetricHistogram scanSizeHisto;
048
049    TableHistograms(DynamicMetricsRegistry registry, TableName tn) {
050      getTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, GET_TIME));
051      incrementTimeHisto = registry.newTimeHistogram(
052          qualifyMetricsName(tn, INCREMENT_TIME));
053      appendTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, APPEND_TIME));
054      putTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_TIME));
055      putBatchTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_BATCH_TIME));
056      deleteTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, DELETE_TIME));
057      deleteBatchTimeHisto = registry.newTimeHistogram(
058          qualifyMetricsName(tn, DELETE_BATCH_TIME));
059      scanTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, SCAN_TIME));
060      scanSizeHisto = registry.newSizeHistogram(qualifyMetricsName(tn, SCAN_SIZE));
061    }
062
063    public void updatePut(long time) {
064      putTimeHisto.add(time);
065    }
066
067    public void updatePutBatch(long time) {
068      putBatchTimeHisto.add(time);
069    }
070
071    public void updateDelete(long t) {
072      deleteTimeHisto.add(t);
073    }
074
075    public void updateDeleteBatch(long t) {
076      deleteBatchTimeHisto.add(t);
077    }
078
079    public void updateGet(long t) {
080      getTimeHisto.add(t);
081    }
082
083    public void updateIncrement(long t) {
084      incrementTimeHisto.add(t);
085    }
086
087    public void updateAppend(long t) {
088      appendTimeHisto.add(t);
089    }
090
091    public void updateScanSize(long scanSize) {
092      scanSizeHisto.add(scanSize);
093    }
094
095    public void updateScanTime(long t) {
096      scanTimeHisto.add(t);
097    }
098  }
099
100  @VisibleForTesting
101  public static String qualifyMetricsName(TableName tableName, String metric) {
102    StringBuilder sb = new StringBuilder();
103    sb.append("Namespace_").append(tableName.getNamespaceAsString());
104    sb.append("_table_").append(tableName.getQualifierAsString());
105    sb.append("_metric_").append(metric);
106    return sb.toString();
107  }
108
109  @VisibleForTesting
110  public TableHistograms getOrCreateTableHistogram(String tableName) {
111    // TODO Java8's ConcurrentHashMap#computeIfAbsent would be stellar instead
112    final TableName tn = TableName.valueOf(tableName);
113    TableHistograms latency = histogramsByTable.get(tn);
114    if (latency == null) {
115      latency = new TableHistograms(getMetricsRegistry(), tn);
116      histogramsByTable.put(tn, latency);
117    }
118    return latency;
119  }
120
121  public MetricsTableLatenciesImpl() {
122    this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
123  }
124
125  public MetricsTableLatenciesImpl(String metricsName, String metricsDescription,
126      String metricsContext, String metricsJmxContext) {
127    super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
128  }
129
130  @Override
131  public void updatePut(String tableName, long t) {
132    getOrCreateTableHistogram(tableName).updatePut(t);
133  }
134
135  @Override
136  public void updatePutBatch(String tableName, long t) {
137    getOrCreateTableHistogram(tableName).updatePutBatch(t);
138  }
139
140  @Override
141  public void updateDelete(String tableName, long t) {
142    getOrCreateTableHistogram(tableName).updateDelete(t);
143  }
144
145  @Override
146  public void updateDeleteBatch(String tableName, long t) {
147    getOrCreateTableHistogram(tableName).updateDeleteBatch(t);
148  }
149
150  @Override
151  public void updateGet(String tableName, long t) {
152    getOrCreateTableHistogram(tableName).updateGet(t);
153  }
154
155  @Override
156  public void updateIncrement(String tableName, long t) {
157    getOrCreateTableHistogram(tableName).updateIncrement(t);
158  }
159
160  @Override
161  public void updateAppend(String tableName, long t) {
162    getOrCreateTableHistogram(tableName).updateAppend(t);
163  }
164
165  @Override
166  public void updateScanSize(String tableName, long scanSize) {
167    getOrCreateTableHistogram(tableName).updateScanSize(scanSize);
168  }
169
170  @Override
171  public void updateScanTime(String tableName, long t) {
172    getOrCreateTableHistogram(tableName).updateScanTime(t);
173  }
174}