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.master; 019 020import java.io.IOException; 021import java.util.AbstractMap.SimpleImmutableEntry; 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.Map.Entry; 027import org.apache.commons.lang3.StringUtils; 028import org.apache.hadoop.hbase.ServerName; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.MasterSwitchType; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.hadoop.hbase.client.TableDescriptor; 033import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 034import org.apache.hadoop.hbase.procedure2.Procedure; 035import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 036import org.apache.hadoop.hbase.quotas.MasterQuotaManager; 037import org.apache.hadoop.hbase.quotas.QuotaObserverChore; 038import org.apache.hadoop.hbase.quotas.QuotaUtil; 039import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot; 040import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 041import org.apache.hadoop.hbase.util.PairOfSameType; 042import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 043import org.apache.yetus.audience.InterfaceAudience; 044 045/** 046 * Impl for exposing HMaster Information through JMX 047 */ 048@InterfaceAudience.Private 049public class MetricsMasterWrapperImpl implements MetricsMasterWrapper { 050 051 private final HMaster master; 052 053 public MetricsMasterWrapperImpl(final HMaster master) { 054 this.master = master; 055 } 056 057 @Override 058 public double getAverageLoad() { 059 return master.getAverageLoad(); 060 } 061 062 @Override 063 public long getSplitPlanCount() { 064 if (master.getRegionNormalizerManager() == null) { 065 return 0; 066 } 067 return master.getRegionNormalizerManager().getSplitPlanCount(); 068 } 069 070 @Override 071 public long getMergePlanCount() { 072 if (master.getRegionNormalizerManager() == null) { 073 return 0; 074 } 075 return master.getRegionNormalizerManager().getMergePlanCount(); 076 } 077 078 @Override 079 public long getMasterInitializationTime() { 080 return master.getMasterFinishedInitializationTime(); 081 } 082 083 @Override 084 public String getClusterId() { 085 return master.getClusterId(); 086 } 087 088 @Override 089 public String getZookeeperQuorum() { 090 ZKWatcher zk = master.getZooKeeper(); 091 if (zk == null) { 092 return ""; 093 } 094 return zk.getQuorum(); 095 } 096 097 @Override 098 public String[] getCoprocessors() { 099 return master.getMasterCoprocessors(); 100 } 101 102 @Override 103 public long getStartTime() { 104 return master.getMasterStartTime(); 105 } 106 107 @Override 108 public long getActiveTime() { 109 return master.getMasterActiveTime(); 110 } 111 112 @Override 113 public String getRegionServers() { 114 ServerManager serverManager = this.master.getServerManager(); 115 if (serverManager == null) { 116 return ""; 117 } 118 return StringUtils.join(serverManager.getOnlineServers().keySet(), ";"); 119 } 120 121 @Override 122 public int getNumRegionServers() { 123 ServerManager serverManager = this.master.getServerManager(); 124 if (serverManager == null) { 125 return 0; 126 } 127 return serverManager.getOnlineServers().size(); 128 } 129 130 @Override 131 public String getDeadRegionServers() { 132 ServerManager serverManager = this.master.getServerManager(); 133 if (serverManager == null) { 134 return ""; 135 } 136 return StringUtils.join(serverManager.getDeadServers().copyServerNames(), ";"); 137 } 138 139 @Override 140 public int getNumDeadRegionServers() { 141 ServerManager serverManager = this.master.getServerManager(); 142 if (serverManager == null) { 143 return 0; 144 } 145 return serverManager.getDeadServers().size(); 146 } 147 148 @Override 149 public boolean isRunning() { 150 return !(master.isStopped() || master.isStopping()); 151 } 152 153 @Override 154 public String getDrainingRegionServers() { 155 ServerManager serverManager = this.master.getServerManager(); 156 if (serverManager == null) { 157 return ""; 158 } 159 return StringUtils.join(serverManager.getDrainingServersList(), ";"); 160 } 161 162 @Override 163 public int getNumDrainingRegionServers() { 164 ServerManager serverManager = this.master.getServerManager(); 165 if (serverManager == null) { 166 return 0; 167 } 168 return serverManager.getDrainingServersList().size(); 169 } 170 171 @Override 172 public String getServerName() { 173 ServerName serverName = master.getServerName(); 174 if (serverName == null) { 175 return ""; 176 } 177 return serverName.getServerName(); 178 } 179 180 @Override 181 public boolean getIsActiveMaster() { 182 return master.isActiveMaster(); 183 } 184 185 @Override 186 public long getNumWALFiles() { 187 return master.getNumWALFiles(); 188 } 189 190 @Override 191 public Map<String, Long> getOldestProcedureAgeByType() { 192 ProcedureExecutor<MasterProcedureEnv> procedureExecutor = master.getMasterProcedureExecutor(); 193 if (procedureExecutor == null) { 194 return Collections.emptyMap(); 195 } 196 long now = EnvironmentEdgeManager.currentTime(); 197 Map<String, Long> oldestProcedureAgeByType = new HashMap<>(); 198 for (Procedure<MasterProcedureEnv> procedure : procedureExecutor.getProcedures()) { 199 if (!procedure.isFinished()) { 200 long age = Math.max(0L, now - procedure.getSubmittedTime()); 201 oldestProcedureAgeByType.merge(procedure.getClass().getSimpleName(), age, Math::max); 202 } 203 } 204 return oldestProcedureAgeByType; 205 } 206 207 @Override 208 public Map<String, Entry<Long, Long>> getTableSpaceUtilization() { 209 if (master == null) { 210 return Collections.emptyMap(); 211 } 212 QuotaObserverChore quotaChore = master.getQuotaObserverChore(); 213 if (quotaChore == null) { 214 return Collections.emptyMap(); 215 } 216 Map<TableName, SpaceQuotaSnapshot> tableSnapshots = quotaChore.getTableQuotaSnapshots(); 217 Map<String, Entry<Long, Long>> convertedData = new HashMap<>(); 218 for (Entry<TableName, SpaceQuotaSnapshot> entry : tableSnapshots.entrySet()) { 219 convertedData.put(entry.getKey().toString(), convertSnapshot(entry.getValue())); 220 } 221 return convertedData; 222 } 223 224 @Override 225 public Map<String, Entry<Long, Long>> getNamespaceSpaceUtilization() { 226 QuotaObserverChore quotaChore = master.getQuotaObserverChore(); 227 if (quotaChore == null) { 228 return Collections.emptyMap(); 229 } 230 Map<String, SpaceQuotaSnapshot> namespaceSnapshots = quotaChore.getNamespaceQuotaSnapshots(); 231 Map<String, Entry<Long, Long>> convertedData = new HashMap<>(); 232 for (Entry<String, SpaceQuotaSnapshot> entry : namespaceSnapshots.entrySet()) { 233 convertedData.put(entry.getKey(), convertSnapshot(entry.getValue())); 234 } 235 return convertedData; 236 } 237 238 Entry<Long, Long> convertSnapshot(SpaceQuotaSnapshot snapshot) { 239 return new SimpleImmutableEntry<Long, Long>(snapshot.getUsage(), snapshot.getLimit()); 240 } 241 242 @Override 243 public PairOfSameType<Integer> getRegionCounts() { 244 try { 245 if (!master.isInitialized()) { 246 return new PairOfSameType<>(0, 0); 247 } 248 Integer onlineRegionCount = 0; 249 Integer offlineRegionCount = 0; 250 251 List<TableDescriptor> descriptors = master.listTableDescriptors(null, null, null, false); 252 253 for (TableDescriptor htDesc : descriptors) { 254 TableName tableName = htDesc.getTableName(); 255 Map<RegionState.State, List<RegionInfo>> tableRegions = 256 master.getAssignmentManager().getRegionStates().getRegionByStateOfTable(tableName); 257 onlineRegionCount += tableRegions.get(RegionState.State.OPEN).size(); 258 offlineRegionCount += tableRegions.get(RegionState.State.OFFLINE).size(); 259 } 260 return new PairOfSameType<>(onlineRegionCount, offlineRegionCount); 261 } catch (IOException e) { 262 return new PairOfSameType<>(0, 0); 263 } 264 } 265 266 @Override 267 public long getOldWALsDirSize() { 268 if (master == null || !master.isInitialized()) { 269 return 0; 270 } 271 return master.getMasterWalManager().getOldWALsDirSize(); 272 } 273 274 @Override 275 public Map<String, Integer> getSwitchStates() { 276 if (!master.isActiveMaster() || !master.isInitialized()) { 277 return Collections.emptyMap(); 278 } 279 Map<String, Integer> states = new HashMap<>(); 280 states.put(MetricsMasterSource.BALANCER_ENABLED_NAME, master.isBalancerOn() ? 1 : 0); 281 states.put(MetricsMasterSource.NORMALIZER_ENABLED_NAME, master.isNormalizerOn() ? 1 : 0); 282 states.put(MetricsMasterSource.SPLIT_ENABLED_NAME, 283 master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT) ? 1 : 0); 284 states.put(MetricsMasterSource.MERGE_ENABLED_NAME, 285 master.isSplitOrMergeEnabled(MasterSwitchType.MERGE) ? 1 : 0); 286 states.put(MetricsMasterSource.CLEANER_CHORE_ENABLED_NAME, 287 master.isCleanerChoreEnabled() ? 1 : 0); 288 states.put(MetricsMasterSource.CATALOG_JANITOR_ENABLED_NAME, 289 master.isCatalogJanitorEnabled() ? 1 : 0); 290 states.put(MetricsMasterSource.SNAPSHOT_CLEANUP_ENABLED_NAME, 291 master.snapshotCleanupStateStore.get() ? 1 : 0); 292 states.put(MetricsMasterSource.REPLICATION_PEER_MODIFICATION_ENABLED_NAME, 293 master.isReplicationPeerModificationEnabled() ? 1 : 0); 294 MasterQuotaManager quotaManager = master.getMasterQuotaManager(); 295 if (quotaManager != null) { 296 states.put(MetricsMasterSource.RPC_THROTTLE_ENABLED_NAME, 297 quotaManager.isRpcThrottleEnabled() ? 1 : 0); 298 } else if (!QuotaUtil.isQuotaEnabled(master.getConfiguration())) { 299 states.put(MetricsMasterSource.RPC_THROTTLE_ENABLED_NAME, 0); 300 } 301 return states; 302 } 303}