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.hbtop.mode;
019
020import edu.umd.cs.findbugs.annotations.Nullable;
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027import org.apache.commons.lang3.time.FastDateFormat;
028import org.apache.hadoop.hbase.ClusterMetrics;
029import org.apache.hadoop.hbase.RegionMetrics;
030import org.apache.hadoop.hbase.ServerMetrics;
031import org.apache.hadoop.hbase.TableName;
032import org.apache.hadoop.hbase.client.RegionInfo;
033import org.apache.hadoop.hbase.hbtop.Record;
034import org.apache.hadoop.hbase.hbtop.field.Field;
035import org.apache.hadoop.hbase.hbtop.field.FieldInfo;
036import org.apache.hadoop.hbase.util.Bytes;
037import org.apache.yetus.audience.InterfaceAudience;
038
039
040/**
041 * Implementation for {@link ModeStrategy} for Region Mode.
042 */
043@InterfaceAudience.Private
044public final class RegionModeStrategy implements ModeStrategy {
045
046  private final List<FieldInfo> fieldInfos = Arrays.asList(
047    new FieldInfo(Field.REGION_NAME, 0, false),
048    new FieldInfo(Field.NAMESPACE, 0, true),
049    new FieldInfo(Field.TABLE, 0,  true),
050    new FieldInfo(Field.START_CODE, 13, false),
051    new FieldInfo(Field.REPLICA_ID, 5, false),
052    new FieldInfo(Field.REGION, 32, true),
053    new FieldInfo(Field.REGION_SERVER, 0, true),
054    new FieldInfo(Field.LONG_REGION_SERVER, 0, false),
055    new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 8, true),
056    new FieldInfo(Field.READ_REQUEST_COUNT_PER_SECOND, 8, true),
057    new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 8, true),
058    new FieldInfo(Field.WRITE_REQUEST_COUNT_PER_SECOND, 8, true),
059    new FieldInfo(Field.STORE_FILE_SIZE, 10, true),
060    new FieldInfo(Field.UNCOMPRESSED_STORE_FILE_SIZE, 12, false),
061    new FieldInfo(Field.NUM_STORE_FILES,4, true),
062    new FieldInfo(Field.MEM_STORE_SIZE, 8, true),
063    new FieldInfo(Field.LOCALITY, 8, true),
064    new FieldInfo(Field.START_KEY, 0, false),
065    new FieldInfo(Field.COMPACTING_CELL_COUNT, 12, false),
066    new FieldInfo(Field.COMPACTED_CELL_COUNT, 12, false),
067    new FieldInfo(Field.COMPACTION_PROGRESS, 7, false),
068    new FieldInfo(Field.LAST_MAJOR_COMPACTION_TIME, 19, false)
069  );
070
071  private final Map<String, RequestCountPerSecond> requestCountPerSecondMap = new HashMap<>();
072
073  RegionModeStrategy() {
074  }
075
076  @Override
077  public List<FieldInfo> getFieldInfos() {
078    return fieldInfos;
079  }
080
081  @Override
082  public Field getDefaultSortField() {
083    return Field.REQUEST_COUNT_PER_SECOND;
084  }
085
086  @Override
087  public List<Record> getRecords(ClusterMetrics clusterMetrics) {
088    List<Record> ret = new ArrayList<>();
089    for (ServerMetrics sm : clusterMetrics.getLiveServerMetrics().values()) {
090      long lastReportTimestamp = sm.getLastReportTimestamp();
091      for (RegionMetrics rm : sm.getRegionMetrics().values()) {
092        ret.add(createRecord(sm, rm, lastReportTimestamp));
093      }
094    }
095    return ret;
096  }
097
098  private Record createRecord(ServerMetrics serverMetrics, RegionMetrics regionMetrics,
099    long lastReportTimestamp) {
100
101    Record.Builder builder = Record.builder();
102
103    String regionName = regionMetrics.getNameAsString();
104    builder.put(Field.REGION_NAME, regionName);
105
106    String namespaceName = "";
107    String tableName = "";
108    String region = "";
109    String startKey = "";
110    String startCode = "";
111    String replicaId = "";
112    try {
113      byte[][] elements = RegionInfo.parseRegionName(regionMetrics.getRegionName());
114      TableName tn = TableName.valueOf(elements[0]);
115      namespaceName = tn.getNamespaceAsString();
116      tableName = tn.getQualifierAsString();
117      startKey = Bytes.toStringBinary(elements[1]);
118      startCode = Bytes.toString(elements[2]);
119      replicaId = elements.length == 4 ?
120        Integer.valueOf(Bytes.toString(elements[3])).toString() : "";
121      region = RegionInfo.encodeRegionName(regionMetrics.getRegionName());
122    } catch (IOException ignored) {
123    }
124
125    builder.put(Field.NAMESPACE, namespaceName);
126    builder.put(Field.TABLE, tableName);
127    builder.put(Field.START_CODE, startCode);
128    builder.put(Field.REPLICA_ID, replicaId);
129    builder.put(Field.REGION, region);
130    builder.put(Field.START_KEY, startKey);
131    builder.put(Field.REGION_SERVER, serverMetrics.getServerName().toShortString());
132    builder.put(Field.LONG_REGION_SERVER, serverMetrics.getServerName().getServerName());
133
134    RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(regionName);
135    if (requestCountPerSecond == null) {
136      requestCountPerSecond = new RequestCountPerSecond();
137      requestCountPerSecondMap.put(regionName, requestCountPerSecond);
138    }
139    requestCountPerSecond.refresh(lastReportTimestamp, regionMetrics.getReadRequestCount(),
140      regionMetrics.getFilteredReadRequestCount(), regionMetrics.getWriteRequestCount());
141
142    builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,
143      requestCountPerSecond.getReadRequestCountPerSecond());
144    builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,
145        requestCountPerSecond.getFilteredReadRequestCountPerSecond());
146    builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,
147      requestCountPerSecond.getWriteRequestCountPerSecond());
148    builder.put(Field.REQUEST_COUNT_PER_SECOND,
149      requestCountPerSecond.getRequestCountPerSecond());
150
151    builder.put(Field.STORE_FILE_SIZE, regionMetrics.getStoreFileSize());
152    builder.put(Field.UNCOMPRESSED_STORE_FILE_SIZE, regionMetrics.getUncompressedStoreFileSize());
153    builder.put(Field.NUM_STORE_FILES, regionMetrics.getStoreFileCount());
154    builder.put(Field.MEM_STORE_SIZE, regionMetrics.getMemStoreSize());
155    builder.put(Field.LOCALITY, regionMetrics.getDataLocality());
156
157    long compactingCellCount = regionMetrics.getCompactingCellCount();
158    long compactedCellCount = regionMetrics.getCompactedCellCount();
159    float compactionProgress = 0;
160    if  (compactedCellCount > 0) {
161      compactionProgress = 100 * ((float) compactedCellCount / compactingCellCount);
162    }
163
164    builder.put(Field.COMPACTING_CELL_COUNT, compactingCellCount);
165    builder.put(Field.COMPACTED_CELL_COUNT, compactedCellCount);
166    builder.put(Field.COMPACTION_PROGRESS, compactionProgress);
167
168    FastDateFormat df = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
169    long lastMajorCompactionTimestamp = regionMetrics.getLastMajorCompactionTimestamp();
170
171    builder.put(Field.LAST_MAJOR_COMPACTION_TIME,
172      lastMajorCompactionTimestamp == 0 ? "" : df.format(lastMajorCompactionTimestamp));
173
174    return builder.build();
175  }
176
177  @Nullable
178  @Override
179  public DrillDownInfo drillDown(Record selectedRecord) {
180    // do nothing
181    return null;
182  }
183}