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