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