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.Map;
020import java.util.concurrent.ConcurrentHashMap;
021
022import org.apache.hadoop.hbase.TableName;
023import org.apache.hadoop.hbase.metrics.Meter;
024import org.apache.hadoop.hbase.metrics.MetricRegistry;
025import org.apache.yetus.audience.InterfaceAudience;
026
027/**
028 * Implementation of {@link MetricsTableQueryMeter} to track query per second for each table in
029 * a RegionServer.
030 */
031@InterfaceAudience.Private
032public class MetricsTableQueryMeterImpl implements MetricsTableQueryMeter {
033  private final Map<TableName, TableMeters> metersByTable = new ConcurrentHashMap<>();
034  private final MetricRegistry metricRegistry;
035
036  private final static String TABLE_READ_QUERY_PER_SECOND = "tableReadQueryPerSecond";
037  private final static String TABLE_WRITE_QUERY_PER_SECOND = "tableWriteQueryPerSecond";
038
039  public MetricsTableQueryMeterImpl(MetricRegistry metricRegistry) {
040    this.metricRegistry = metricRegistry;
041  }
042
043  private static class TableMeters {
044    final Meter tableReadQueryMeter;
045    final Meter tableWriteQueryMeter;
046
047    TableMeters(MetricRegistry metricRegistry, TableName tableName) {
048      this.tableReadQueryMeter = metricRegistry.meter(qualifyMetricsName(tableName,
049        TABLE_READ_QUERY_PER_SECOND));
050      this.tableWriteQueryMeter =
051        metricRegistry.meter(qualifyMetricsName(tableName, TABLE_WRITE_QUERY_PER_SECOND));
052    }
053
054    public void updateTableReadQueryMeter(long count) {
055      tableReadQueryMeter.mark(count);
056    }
057
058    public void updateTableReadQueryMeter() {
059      tableReadQueryMeter.mark();
060    }
061
062    public void updateTableWriteQueryMeter(long count) {
063      tableWriteQueryMeter.mark(count);
064    }
065
066    public void updateTableWriteQueryMeter() {
067      tableWriteQueryMeter.mark();
068    }
069  }
070
071  private static String qualifyMetricsName(TableName tableName, String metric) {
072    StringBuilder sb = new StringBuilder();
073    sb.append("Namespace_").append(tableName.getNamespaceAsString());
074    sb.append("_table_").append(tableName.getQualifierAsString());
075    sb.append("_metric_").append(metric);
076    return sb.toString();
077  }
078
079  private TableMeters getOrCreateTableMeter(TableName tableName) {
080    return metersByTable.computeIfAbsent(tableName, tbn -> new TableMeters(metricRegistry, tbn));
081  }
082
083  @Override
084  public void updateTableReadQueryMeter(TableName tableName, long count) {
085    getOrCreateTableMeter(tableName).updateTableReadQueryMeter(count);
086  }
087
088  @Override
089  public void updateTableReadQueryMeter(TableName tableName) {
090    getOrCreateTableMeter(tableName).updateTableReadQueryMeter();
091  }
092
093  @Override
094  public void updateTableWriteQueryMeter(TableName tableName, long count) {
095    getOrCreateTableMeter(tableName).updateTableWriteQueryMeter(count);
096  }
097
098  @Override
099  public void updateTableWriteQueryMeter(TableName tableName) {
100    getOrCreateTableMeter(tableName).updateTableWriteQueryMeter();
101  }
102}