3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 package org
.apache
.hadoop
.hbase
;
22 import edu
.umd
.cs
.findbugs
.annotations
.Nullable
;
23 import java
.util
.Collections
;
24 import java
.util
.EnumSet
;
25 import java
.util
.List
;
27 import java
.util
.TreeMap
;
28 import java
.util
.stream
.Collectors
;
30 import org
.apache
.hadoop
.hbase
.client
.RegionStatesCount
;
31 import org
.apache
.hadoop
.hbase
.master
.RegionState
;
32 import org
.apache
.yetus
.audience
.InterfaceAudience
;
34 import org
.apache
.hbase
.thirdparty
.com
.google
.common
.base
.Preconditions
;
35 import org
.apache
.hbase
.thirdparty
.com
.google
.protobuf
.UnsafeByteOperations
;
36 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.ProtobufUtil
;
37 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.ClusterStatusProtos
;
38 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.ClusterStatusProtos
.Option
;
39 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.FSProtos
;
40 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.HBaseProtos
;
42 @InterfaceAudience.Private
43 public final class ClusterMetricsBuilder
{
45 public static ClusterStatusProtos
.ClusterStatus
toClusterStatus(ClusterMetrics metrics
) {
46 ClusterStatusProtos
.ClusterStatus
.Builder builder
47 = ClusterStatusProtos
.ClusterStatus
.newBuilder()
48 .addAllBackupMasters(metrics
.getBackupMasterNames().stream()
49 .map(ProtobufUtil
::toServerName
).collect(Collectors
.toList()))
50 .addAllDeadServers(metrics
.getDeadServerNames().stream()
51 .map(ProtobufUtil
::toServerName
).collect(Collectors
.toList()))
52 .addAllLiveServers(metrics
.getLiveServerMetrics().entrySet().stream()
53 .map(s
-> ClusterStatusProtos
.LiveServerInfo
55 .setServer(ProtobufUtil
.toServerName(s
.getKey()))
56 .setServerLoad(ServerMetricsBuilder
.toServerLoad(s
.getValue()))
58 .collect(Collectors
.toList()))
59 .addAllMasterCoprocessors(metrics
.getMasterCoprocessorNames().stream()
60 .map(n
-> HBaseProtos
.Coprocessor
.newBuilder().setName(n
).build())
61 .collect(Collectors
.toList()))
62 .addAllRegionsInTransition(metrics
.getRegionStatesInTransition().stream()
63 .map(r
-> ClusterStatusProtos
.RegionInTransition
65 .setSpec(HBaseProtos
.RegionSpecifier
67 .setType(HBaseProtos
.RegionSpecifier
.RegionSpecifierType
.REGION_NAME
)
68 .setValue(UnsafeByteOperations
.unsafeWrap(r
.getRegion().getRegionName()))
70 .setRegionState(r
.convert())
72 .collect(Collectors
.toList()))
73 .setMasterInfoPort(metrics
.getMasterInfoPort())
74 .addAllServersName(metrics
.getServersName().stream().map(ProtobufUtil
::toServerName
)
75 .collect(Collectors
.toList()))
76 .addAllTableRegionStatesCount(metrics
.getTableRegionStatesCount().entrySet().stream()
78 ClusterStatusProtos
.TableRegionStatesCount
.newBuilder()
79 .setTableName(ProtobufUtil
.toProtoTableName((status
.getKey())))
80 .setRegionStatesCount(ProtobufUtil
.toTableRegionStatesCount(status
.getValue()))
82 .collect(Collectors
.toList()));
83 if (metrics
.getMasterName() != null) {
84 builder
.setMaster(ProtobufUtil
.toServerName((metrics
.getMasterName())));
86 if (metrics
.getBalancerOn() != null) {
87 builder
.setBalancerOn(metrics
.getBalancerOn());
89 if (metrics
.getClusterId() != null) {
90 builder
.setClusterId(new ClusterId(metrics
.getClusterId()).convert());
92 if (metrics
.getHBaseVersion() != null) {
93 builder
.setHbaseVersion(
94 FSProtos
.HBaseVersionFileContent
.newBuilder()
95 .setVersion(metrics
.getHBaseVersion()));
97 return builder
.build();
100 public static ClusterMetrics
toClusterMetrics(
101 ClusterStatusProtos
.ClusterStatus proto
) {
102 ClusterMetricsBuilder builder
= ClusterMetricsBuilder
.newBuilder();
103 builder
.setLiveServerMetrics(proto
.getLiveServersList().stream()
104 .collect(Collectors
.toMap(e
-> ProtobufUtil
.toServerName(e
.getServer()),
105 ServerMetricsBuilder
::toServerMetrics
)))
106 .setDeadServerNames(proto
.getDeadServersList().stream()
107 .map(ProtobufUtil
::toServerName
)
108 .collect(Collectors
.toList()))
109 .setBackerMasterNames(proto
.getBackupMastersList().stream()
110 .map(ProtobufUtil
::toServerName
)
111 .collect(Collectors
.toList()))
112 .setRegionsInTransition(proto
.getRegionsInTransitionList().stream()
113 .map(ClusterStatusProtos
.RegionInTransition
::getRegionState
)
114 .map(RegionState
::convert
)
115 .collect(Collectors
.toList()))
116 .setMasterCoprocessorNames(proto
.getMasterCoprocessorsList().stream()
117 .map(HBaseProtos
.Coprocessor
::getName
)
118 .collect(Collectors
.toList()))
119 .setServerNames(proto
.getServersNameList().stream().map(ProtobufUtil
::toServerName
)
120 .collect(Collectors
.toList()))
121 .setTableRegionStatesCount(
122 proto
.getTableRegionStatesCountList().stream()
123 .collect(Collectors
.toMap(
124 e
-> ProtobufUtil
.toTableName(e
.getTableName()),
125 e
-> ProtobufUtil
.toTableRegionStatesCount(e
.getRegionStatesCount()))));
126 if (proto
.hasClusterId()) {
127 builder
.setClusterId(ClusterId
.convert(proto
.getClusterId()).toString());
130 if (proto
.hasHbaseVersion()) {
131 builder
.setHBaseVersion(proto
.getHbaseVersion().getVersion());
134 if (proto
.hasMaster()) {
135 builder
.setMasterName(ProtobufUtil
.toServerName(proto
.getMaster()));
138 if (proto
.hasBalancerOn()) {
139 builder
.setBalancerOn(proto
.getBalancerOn());
142 if (proto
.hasMasterInfoPort()) {
143 builder
.setMasterInfoPort(proto
.getMasterInfoPort());
145 return builder
.build();
149 * Convert ClusterStatusProtos.Option to ClusterMetrics.Option
150 * @param option a ClusterStatusProtos.Option
151 * @return converted ClusterMetrics.Option
153 public static ClusterMetrics
.Option
toOption(ClusterStatusProtos
.Option option
) {
155 case HBASE_VERSION
: return ClusterMetrics
.Option
.HBASE_VERSION
;
156 case LIVE_SERVERS
: return ClusterMetrics
.Option
.LIVE_SERVERS
;
157 case DEAD_SERVERS
: return ClusterMetrics
.Option
.DEAD_SERVERS
;
158 case REGIONS_IN_TRANSITION
: return ClusterMetrics
.Option
.REGIONS_IN_TRANSITION
;
159 case CLUSTER_ID
: return ClusterMetrics
.Option
.CLUSTER_ID
;
160 case MASTER_COPROCESSORS
: return ClusterMetrics
.Option
.MASTER_COPROCESSORS
;
161 case MASTER
: return ClusterMetrics
.Option
.MASTER
;
162 case BACKUP_MASTERS
: return ClusterMetrics
.Option
.BACKUP_MASTERS
;
163 case BALANCER_ON
: return ClusterMetrics
.Option
.BALANCER_ON
;
164 case SERVERS_NAME
: return ClusterMetrics
.Option
.SERVERS_NAME
;
165 case MASTER_INFO_PORT
: return ClusterMetrics
.Option
.MASTER_INFO_PORT
;
166 case TABLE_TO_REGIONS_COUNT
: return ClusterMetrics
.Option
.TABLE_TO_REGIONS_COUNT
;
167 // should not reach here
168 default: throw new IllegalArgumentException("Invalid option: " + option
);
173 * Convert ClusterMetrics.Option to ClusterStatusProtos.Option
174 * @param option a ClusterMetrics.Option
175 * @return converted ClusterStatusProtos.Option
177 public static ClusterStatusProtos
.Option
toOption(ClusterMetrics
.Option option
) {
179 case HBASE_VERSION
: return ClusterStatusProtos
.Option
.HBASE_VERSION
;
180 case LIVE_SERVERS
: return ClusterStatusProtos
.Option
.LIVE_SERVERS
;
181 case DEAD_SERVERS
: return ClusterStatusProtos
.Option
.DEAD_SERVERS
;
182 case REGIONS_IN_TRANSITION
: return ClusterStatusProtos
.Option
.REGIONS_IN_TRANSITION
;
183 case CLUSTER_ID
: return ClusterStatusProtos
.Option
.CLUSTER_ID
;
184 case MASTER_COPROCESSORS
: return ClusterStatusProtos
.Option
.MASTER_COPROCESSORS
;
185 case MASTER
: return ClusterStatusProtos
.Option
.MASTER
;
186 case BACKUP_MASTERS
: return ClusterStatusProtos
.Option
.BACKUP_MASTERS
;
187 case BALANCER_ON
: return ClusterStatusProtos
.Option
.BALANCER_ON
;
188 case SERVERS_NAME
: return Option
.SERVERS_NAME
;
189 case MASTER_INFO_PORT
: return ClusterStatusProtos
.Option
.MASTER_INFO_PORT
;
190 case TABLE_TO_REGIONS_COUNT
: return ClusterStatusProtos
.Option
.TABLE_TO_REGIONS_COUNT
;
191 // should not reach here
192 default: throw new IllegalArgumentException("Invalid option: " + option
);
197 * Convert a list of ClusterStatusProtos.Option to an enum set of ClusterMetrics.Option
198 * @param options the pb options
199 * @return an enum set of ClusterMetrics.Option
201 public static EnumSet
<ClusterMetrics
.Option
> toOptions(List
<ClusterStatusProtos
.Option
> options
) {
202 return options
.stream().map(ClusterMetricsBuilder
::toOption
)
203 .collect(Collectors
.toCollection(() -> EnumSet
.noneOf(ClusterMetrics
.Option
.class)));
207 * Convert an enum set of ClusterMetrics.Option to a list of ClusterStatusProtos.Option
208 * @param options the ClusterMetrics options
209 * @return a list of ClusterStatusProtos.Option
211 public static List
<ClusterStatusProtos
.Option
> toOptions(EnumSet
<ClusterMetrics
.Option
> options
) {
212 return options
.stream().map(ClusterMetricsBuilder
::toOption
).collect(Collectors
.toList());
215 public static ClusterMetricsBuilder
newBuilder() {
216 return new ClusterMetricsBuilder();
219 private String hbaseVersion
;
220 private List
<ServerName
> deadServerNames
= Collections
.emptyList();
221 private Map
<ServerName
, ServerMetrics
> liveServerMetrics
= new TreeMap
<>();
223 private ServerName masterName
;
224 private List
<ServerName
> backupMasterNames
= Collections
.emptyList();
225 private List
<RegionState
> regionsInTransition
= Collections
.emptyList();
227 private String clusterId
;
228 private List
<String
> masterCoprocessorNames
= Collections
.emptyList();
230 private Boolean balancerOn
;
231 private int masterInfoPort
;
232 private List
<ServerName
> serversName
= Collections
.emptyList();
233 private Map
<TableName
, RegionStatesCount
> tableRegionStatesCount
= Collections
.emptyMap();
235 private ClusterMetricsBuilder() {
237 public ClusterMetricsBuilder
setHBaseVersion(String value
) {
238 this.hbaseVersion
= value
;
241 public ClusterMetricsBuilder
setDeadServerNames(List
<ServerName
> value
) {
242 this.deadServerNames
= value
;
246 public ClusterMetricsBuilder
setLiveServerMetrics(Map
<ServerName
, ServerMetrics
> value
) {
247 liveServerMetrics
.putAll(value
);
251 public ClusterMetricsBuilder
setMasterName(ServerName value
) {
252 this.masterName
= value
;
255 public ClusterMetricsBuilder
setBackerMasterNames(List
<ServerName
> value
) {
256 this.backupMasterNames
= value
;
259 public ClusterMetricsBuilder
setRegionsInTransition(List
<RegionState
> value
) {
260 this.regionsInTransition
= value
;
263 public ClusterMetricsBuilder
setClusterId(String value
) {
264 this.clusterId
= value
;
267 public ClusterMetricsBuilder
setMasterCoprocessorNames(List
<String
> value
) {
268 this.masterCoprocessorNames
= value
;
271 public ClusterMetricsBuilder
setBalancerOn(@Nullable Boolean value
) {
272 this.balancerOn
= value
;
275 public ClusterMetricsBuilder
setMasterInfoPort(int value
) {
276 this.masterInfoPort
= value
;
279 public ClusterMetricsBuilder
setServerNames(List
<ServerName
> serversName
) {
280 this.serversName
= serversName
;
284 public ClusterMetricsBuilder
setTableRegionStatesCount(
285 Map
<TableName
, RegionStatesCount
> tableRegionStatesCount
) {
286 this.tableRegionStatesCount
= tableRegionStatesCount
;
290 public ClusterMetrics
build() {
291 return new ClusterMetricsImpl(
299 masterCoprocessorNames
,
303 tableRegionStatesCount
306 private static class ClusterMetricsImpl
implements ClusterMetrics
{
308 private final String hbaseVersion
;
309 private final List
<ServerName
> deadServerNames
;
310 private final Map
<ServerName
, ServerMetrics
> liveServerMetrics
;
312 private final ServerName masterName
;
313 private final List
<ServerName
> backupMasterNames
;
314 private final List
<RegionState
> regionsInTransition
;
316 private final String clusterId
;
317 private final List
<String
> masterCoprocessorNames
;
319 private final Boolean balancerOn
;
320 private final int masterInfoPort
;
321 private final List
<ServerName
> serversName
;
322 private final Map
<TableName
, RegionStatesCount
> tableRegionStatesCount
;
324 ClusterMetricsImpl(String hbaseVersion
, List
<ServerName
> deadServerNames
,
325 Map
<ServerName
, ServerMetrics
> liveServerMetrics
,
326 ServerName masterName
,
327 List
<ServerName
> backupMasterNames
,
328 List
<RegionState
> regionsInTransition
,
330 List
<String
> masterCoprocessorNames
,
333 List
<ServerName
> serversName
,
334 Map
<TableName
, RegionStatesCount
> tableRegionStatesCount
) {
335 this.hbaseVersion
= hbaseVersion
;
336 this.deadServerNames
= Preconditions
.checkNotNull(deadServerNames
);
337 this.liveServerMetrics
= Preconditions
.checkNotNull(liveServerMetrics
);
338 this.masterName
= masterName
;
339 this.backupMasterNames
= Preconditions
.checkNotNull(backupMasterNames
);
340 this.regionsInTransition
= Preconditions
.checkNotNull(regionsInTransition
);
341 this.clusterId
= clusterId
;
342 this.masterCoprocessorNames
= Preconditions
.checkNotNull(masterCoprocessorNames
);
343 this.balancerOn
= balancerOn
;
344 this.masterInfoPort
= masterInfoPort
;
345 this.serversName
= serversName
;
346 this.tableRegionStatesCount
= Preconditions
.checkNotNull(tableRegionStatesCount
);
350 public String
getHBaseVersion() {
355 public List
<ServerName
> getDeadServerNames() {
356 return Collections
.unmodifiableList(deadServerNames
);
360 public Map
<ServerName
, ServerMetrics
> getLiveServerMetrics() {
361 return Collections
.unmodifiableMap(liveServerMetrics
);
365 public ServerName
getMasterName() {
370 public List
<ServerName
> getBackupMasterNames() {
371 return Collections
.unmodifiableList(backupMasterNames
);
375 public List
<RegionState
> getRegionStatesInTransition() {
376 return Collections
.unmodifiableList(regionsInTransition
);
380 public String
getClusterId() {
385 public List
<String
> getMasterCoprocessorNames() {
386 return Collections
.unmodifiableList(masterCoprocessorNames
);
390 public Boolean
getBalancerOn() {
395 public int getMasterInfoPort() {
396 return masterInfoPort
;
400 public List
<ServerName
> getServersName() {
401 return Collections
.unmodifiableList(serversName
);
405 public Map
<TableName
, RegionStatesCount
> getTableRegionStatesCount() {
406 return Collections
.unmodifiableMap(tableRegionStatesCount
);
410 public String
toString() {
411 StringBuilder sb
= new StringBuilder(1024);
412 sb
.append("Master: " + getMasterName());
414 int backupMastersSize
= getBackupMasterNames().size();
415 sb
.append("\nNumber of backup masters: " + backupMastersSize
);
416 if (backupMastersSize
> 0) {
417 for (ServerName serverName
: getBackupMasterNames()) {
418 sb
.append("\n " + serverName
);
422 int serversSize
= getLiveServerMetrics().size();
423 int serversNameSize
= getServersName().size();
424 sb
.append("\nNumber of live region servers: "
425 + (serversSize
> 0 ? serversSize
: serversNameSize
));
426 if (serversSize
> 0) {
427 for (ServerName serverName
: getLiveServerMetrics().keySet()) {
428 sb
.append("\n " + serverName
.getServerName());
430 } else if (serversNameSize
> 0) {
431 for (ServerName serverName
: getServersName()) {
432 sb
.append("\n " + serverName
.getServerName());
436 int deadServerSize
= getDeadServerNames().size();
437 sb
.append("\nNumber of dead region servers: " + deadServerSize
);
438 if (deadServerSize
> 0) {
439 for (ServerName serverName
: getDeadServerNames()) {
440 sb
.append("\n " + serverName
);
444 sb
.append("\nAverage load: " + getAverageLoad());
445 sb
.append("\nNumber of requests: " + getRequestCount());
446 sb
.append("\nNumber of regions: " + getRegionCount());
448 int ritSize
= getRegionStatesInTransition().size();
449 sb
.append("\nNumber of regions in transition: " + ritSize
);
451 for (RegionState state
: getRegionStatesInTransition()) {
452 sb
.append("\n " + state
.toDescriptiveString());
455 return sb
.toString();