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 */
018package org.apache.hadoop.hbase.regionserver;
019
020import java.util.HashMap;
021import org.apache.hadoop.hbase.TableName;
022import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
023import org.apache.hadoop.metrics2.MetricHistogram;
024import org.apache.hadoop.metrics2.MetricsCollector;
025import org.apache.hadoop.metrics2.MetricsRecordBuilder;
026import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry;
027import org.apache.yetus.audience.InterfaceAudience;
028
029/**
030 * Implementation of {@link MetricsTableLatencies} to track latencies for one table in a
031 * RegionServer.
032 */
033@InterfaceAudience.Private
034public class MetricsTableLatenciesImpl extends BaseSourceImpl implements MetricsTableLatencies {
035
036  private final HashMap<TableName, TableHistograms> histogramsByTable = new HashMap<>();
037
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    final MetricHistogram checkAndDeleteTimeHisto;
049    final MetricHistogram checkAndPutTimeHisto;
050    final MetricHistogram checkAndMutateTimeHisto;
051
052    TableHistograms(DynamicMetricsRegistry registry, TableName tn) {
053      getTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, GET_TIME));
054      incrementTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, INCREMENT_TIME));
055      appendTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, APPEND_TIME));
056      putTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_TIME));
057      putBatchTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_BATCH_TIME));
058      deleteTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, DELETE_TIME));
059      deleteBatchTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, DELETE_BATCH_TIME));
060      scanTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, SCAN_TIME));
061      scanSizeHisto = registry.newSizeHistogram(qualifyMetricsName(tn, SCAN_SIZE));
062      checkAndDeleteTimeHisto =
063        registry.newTimeHistogram(qualifyMetricsName(tn, CHECK_AND_DELETE_TIME));
064      checkAndPutTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, CHECK_AND_PUT_TIME));
065      checkAndMutateTimeHisto =
066        registry.newTimeHistogram(qualifyMetricsName(tn, CHECK_AND_MUTATE_TIME));
067    }
068
069    public void updatePut(long time) {
070      putTimeHisto.add(time);
071    }
072
073    public void updatePutBatch(long time) {
074      putBatchTimeHisto.add(time);
075    }
076
077    public void updateDelete(long t) {
078      deleteTimeHisto.add(t);
079    }
080
081    public void updateDeleteBatch(long t) {
082      deleteBatchTimeHisto.add(t);
083    }
084
085    public void updateGet(long t) {
086      getTimeHisto.add(t);
087    }
088
089    public void updateIncrement(long t) {
090      incrementTimeHisto.add(t);
091    }
092
093    public void updateAppend(long t) {
094      appendTimeHisto.add(t);
095    }
096
097    public void updateScanSize(long scanSize) {
098      scanSizeHisto.add(scanSize);
099    }
100
101    public void updateScanTime(long t) {
102      scanTimeHisto.add(t);
103    }
104
105    public void updateCheckAndDeleteTime(long t) {
106      checkAndDeleteTimeHisto.add(t);
107    }
108
109    public void updateCheckAndPutTime(long t) {
110      checkAndPutTimeHisto.add(t);
111    }
112
113    public void updateCheckAndMutateTime(long t) {
114      checkAndMutateTimeHisto.add(t);
115    }
116  }
117
118  public static String qualifyMetricsName(TableName tableName, String metric) {
119    StringBuilder sb = new StringBuilder();
120    sb.append("Namespace_").append(tableName.getNamespaceAsString());
121    sb.append("_table_").append(tableName.getQualifierAsString());
122    sb.append("_metric_").append(metric);
123    return sb.toString();
124  }
125
126  public TableHistograms getOrCreateTableHistogram(String tableName) {
127    // TODO Java8's ConcurrentHashMap#computeIfAbsent would be stellar instead
128    final TableName tn = TableName.valueOf(tableName);
129    TableHistograms latency = histogramsByTable.get(tn);
130    if (latency == null) {
131      latency = new TableHistograms(getMetricsRegistry(), tn);
132      histogramsByTable.put(tn, latency);
133    }
134    return latency;
135  }
136
137  public MetricsTableLatenciesImpl() {
138    this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
139  }
140
141  public MetricsTableLatenciesImpl(String metricsName, String metricsDescription,
142    String metricsContext, String metricsJmxContext) {
143    super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
144  }
145
146  @Override
147  public void updatePut(String tableName, long t) {
148    getOrCreateTableHistogram(tableName).updatePut(t);
149  }
150
151  @Override
152  public void updatePutBatch(String tableName, long t) {
153    getOrCreateTableHistogram(tableName).updatePutBatch(t);
154  }
155
156  @Override
157  public void updateDelete(String tableName, long t) {
158    getOrCreateTableHistogram(tableName).updateDelete(t);
159  }
160
161  @Override
162  public void updateDeleteBatch(String tableName, long t) {
163    getOrCreateTableHistogram(tableName).updateDeleteBatch(t);
164  }
165
166  @Override
167  public void updateGet(String tableName, long t) {
168    getOrCreateTableHistogram(tableName).updateGet(t);
169  }
170
171  @Override
172  public void updateIncrement(String tableName, long t) {
173    getOrCreateTableHistogram(tableName).updateIncrement(t);
174  }
175
176  @Override
177  public void updateAppend(String tableName, long t) {
178    getOrCreateTableHistogram(tableName).updateAppend(t);
179  }
180
181  @Override
182  public void updateScanSize(String tableName, long scanSize) {
183    getOrCreateTableHistogram(tableName).updateScanSize(scanSize);
184  }
185
186  @Override
187  public void updateScanTime(String tableName, long t) {
188    getOrCreateTableHistogram(tableName).updateScanTime(t);
189  }
190
191  @Override
192  public void updateCheckAndDelete(String tableName, long time) {
193    getOrCreateTableHistogram(tableName).updateCheckAndDeleteTime(time);
194  }
195
196  @Override
197  public void updateCheckAndPut(String tableName, long time) {
198    getOrCreateTableHistogram(tableName).updateCheckAndPutTime(time);
199  }
200
201  @Override
202  public void updateCheckAndMutate(String tableName, long time) {
203    getOrCreateTableHistogram(tableName).updateCheckAndMutateTime(time);
204  }
205
206  @Override
207  public void getMetrics(MetricsCollector metricsCollector, boolean all) {
208    MetricsRecordBuilder mrb = metricsCollector.addRecord(metricsName);
209    // source is registered in supers constructor, sometimes called before the whole initialization.
210    metricsRegistry.snapshot(mrb, all);
211    if (metricsAdapter != null) {
212      // snapshot MetricRegistry as well
213      metricsAdapter.snapshotAllMetrics(registry, mrb);
214    }
215  }
216}