You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2021/08/05 01:06:14 UTC
[hbase] branch branch-1 updated: HBASE-25469 Add detailed RIT info
in JSON format for consumption as metrics (#3557)
This is an automated email from the ASF dual-hosted git repository.
apurtell pushed a commit to branch branch-1
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-1 by this push:
new 8c18563 HBASE-25469 Add detailed RIT info in JSON format for consumption as metrics (#3557)
8c18563 is described below
commit 8c18563cad3fcf9e743deff74474a11c1f0b5fd8
Author: caroliney14 <ca...@berkeley.edu>
AuthorDate: Wed Aug 4 18:05:39 2021 -0700
HBASE-25469 Add detailed RIT info in JSON format for consumption as metrics (#3557)
Signed-off-by: Andrew Purtell <ap...@apache.org>
---
.../tmpl/master/AssignmentManagerStatusTmpl.jamon | 2 +-
.../hbase/tmpl/master/MasterStatusTmpl.jamon | 13 +-
.../main/resources/hbase-webapps/master/rits.jsp | 180 +++++++++++++++++++++
3 files changed, 191 insertions(+), 4 deletions(-)
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
index f97860b..8ca80a6 100644
--- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
+++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
@@ -73,7 +73,7 @@ int numOfPages = (int) Math.ceil(numOfRITs * 1.0 / ritsPerPage);
</%java>
<section>
<h2>Regions in Transition</h2>
- <p><% numOfRITs %> region(s) in transition.
+ <p><a href="/rits.jsp"><% numOfRITs %> region(s) in transition.</a>
<%if !ritsTwiceThreshold.isEmpty() %>
<span class="label label-danger" style="font-size:100%;font-weight:normal">
<%elseif !ritsOverThreshold.isEmpty() %>
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
index 0d02f99..0b331b8 100644
--- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
+++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon
@@ -195,6 +195,10 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
</div>
</%if>
+ <%if master.getAssignmentManager() != null %>
+ <& AssignmentManagerStatusTmpl; assignmentManager=master.getAssignmentManager()&>
+ </%if>
+
<section>
<h2>Region Servers</h2>
<& RegionServerListTmpl; master= master; servers = servers &>
@@ -241,9 +245,6 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
<h2>Peers</h2>
<& peerConfigs &>
</section>
- <%if master.getAssignmentManager() != null %>
- <& AssignmentManagerStatusTmpl; assignmentManager=master.getAssignmentManager()&>
- </%if>
<%else>
<section>
<& BackupMasterStatusTmpl; master = master &>
@@ -472,6 +473,9 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
master.getAssignmentManager().getRegionStates()
.getRegionByStateOfTable(tableName);
int openRegionsCount = tableRegions.get(RegionState.State.OPEN).size();
+ int openingRegionsCount = tableRegions.get(RegionState.State.OPENING).size();
+ int closedRegionsCount = tableRegions.get(RegionState.State.CLOSED).size();
+ int closingRegionsCount = tableRegions.get(RegionState.State.CLOSING).size();
int offlineRegionsCount = tableRegions.get(RegionState.State.OFFLINE).size();
int splitRegionsCount = tableRegions.get(RegionState.State.SPLIT).size();
int failedRegionsCount = tableRegions.get(RegionState.State.FAILED_OPEN).size()
@@ -492,6 +496,9 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
<td align="center"><% frags.get(tableName.getNameAsString()) != null ? frags.get(tableName.getNameAsString()).intValue() + "%" : "n/a" %></td>
</%if>
<td><% openRegionsCount %></td>
+ <%if (openingRegionsCount > 0) %> <td><a href="/rits.jsp?table=<% tableName.getNameAsString() %>&state=OPENING"><% openingRegionsCount %></td> <%else><td><% openingRegionsCount %></td> </%if>
+ <td><% closedRegionsCount %></td>
+ <%if (closingRegionsCount > 0) %> <td><a href="/rits.jsp?table=<% tableName.getNameAsString() %>&state=CLOSING"><% closingRegionsCount %></td> <%else><td><% closingRegionsCount %></td> </%if>
<td><% offlineRegionsCount %></td>
<td><% failedRegionsCount %></td>
<td><% splitRegionsCount %></td>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rits.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rits.jsp
new file mode 100644
index 0000000..cf21acb
--- /dev/null
+++ b/hbase-server/src/main/resources/hbase-webapps/master/rits.jsp
@@ -0,0 +1,180 @@
+<%--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+--%>
+<%@ page contentType="text/html;charset=UTF-8"
+ import="java.util.ArrayList"
+ import="java.util.List"
+ import="java.util.HashMap"
+ import="java.util.HashSet"
+ import="java.util.Map"
+ import="java.util.Set"
+ import="org.apache.hadoop.hbase.HBaseConfiguration"
+ import="org.apache.hadoop.hbase.master.HMaster"
+ import="org.apache.hadoop.hbase.master.RegionState"
+ import="org.apache.hadoop.hbase.util.GsonUtil"
+ import="org.apache.hbase.thirdparty.com.google.gson.Gson"
+%>
+<%
+ HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER);
+ Set<RegionState> rit = master.getAssignmentManager().getRegionStates().getRegionsInTransition();
+ String table = request.getParameter("table");
+ String state = request.getParameter("state");
+ if (table != null && state != null && !table.equals("null") && !state.equals("null")) {
+ Set<RegionState> ritFiltered = new HashSet<>();
+ for (RegionState regionState: rit) {
+ if (regionState.getRegion().getTable().getNameAsString().equals(table) &&
+ regionState.getState().name().equals(state)){
+ ritFiltered.add(regionState);
+ }
+ }
+ rit = ritFiltered;
+ }
+
+ String format = request.getParameter("format");
+ if(format == null || format.isEmpty()){
+ format = "html";
+ }
+ String filter = request.getParameter("filter");
+%>
+
+
+<% if (format.equals("html")) { %>
+<!--[if IE]>
+<!DOCTYPE html>
+<![endif]-->
+<?xml version="1.0" encoding="UTF-8" ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta charset="utf-8">
+ <title>HBase Master Procedures: <%= master.getServerName() %></title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+ <meta name="author" content="">
+
+ <link href="/static/css/bootstrap.min.css" rel="stylesheet">
+ <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
+ <link href="/static/css/hbase.css" rel="stylesheet">
+</head>
+<body>
+<div class="navbar navbar-fixed-top navbar-default">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="/master-status"><img src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
+ </div>
+ <div class="collapse navbar-collapse">
+ <ul class="nav navbar-nav">
+ <li><a href="/master-status">Home</a></li>
+ <li><a href="/tablesDetailed.jsp">Table Details</a></li>
+ <li><a href="/procedures.jsp">Procedures</a></li>
+ <li><a href="/logs/">Local Logs</a></li>
+ <li><a href="/logLevel">Log Level</a></li>
+ <li><a href="/dump">Debug Dump</a></li>
+ <li><a href="/jmx">Metrics Dump</a></li>
+ <li><a href="/prof">Profiler</a></li>
+ <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+ <li><a href="/conf">HBase Configuration</a></li>
+ <% } %>
+ </ul>
+ </div><!--/.nav-collapse -->
+ </div>
+</div>
+<div class="container-fluid content">
+ <div class="row">
+ <div class="page-header">
+ <h1>Regions in transition</h1>
+ </div>
+ </div>
+ <div class="row">
+ <div class="page-header">
+ <a href="/rits.jsp?format=txt&filter=region&table=<%=table%>&state=<%=state%>" class="btn btn-primary">Regions in text format</a>
+ <a href="/rits.jsp?format=json&table=<%=table%>&state=<%=state%>" class="btn btn-info">RIT info as JSON</a>
+ <p>regions in text format can be copied and passed to command-line utils such as hbck2</p>
+ </div>
+ </div>
+
+ <% if (rit != null && rit.size() > 0) { %>
+ <table class="table table-striped">
+ <tr>
+ <th>Region</th>
+ <th>Table</th>
+ <th>RegionState</th>
+ <th>Server</th>
+ <th>Start Time</th>
+ <th>Duration (ms)</th>
+ </tr>
+ <% for (RegionState regionState : rit) { %>
+ <tr>
+ <td><%= regionState.getRegion().getEncodedName() %></td>
+ <td><%= regionState.getRegion().getTable() %></td>
+ <td><%= regionState.getState() %></td>
+ <td><%= regionState.getServerName() %></td>
+ <td><%= regionState.getStamp() %></td>
+ <td><%= regionState.getRitDuration() %></td>
+ </tr>
+ <% } %>
+ <p><%= rit.size() %> region(s) in transition.</p>
+ </table>
+ <% } else { %>
+ <p> no region in transition right now. </p>
+ <% } %>
+</div>
+<script src="/static/js/jquery.min.js" type="text/javascript"></script>
+<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+
+</body>
+</html>
+<% } else if (format.equals("json")) { %>
+ <%
+ Gson GSON = GsonUtil.createGson().create();
+ Map<String, List<Map<String, Object>>> map = new HashMap<>();
+ List<Map<String, Object>> rits = new ArrayList<>();
+ map.put("rits", rits);
+ for (RegionState regionState : rit) {
+ Map<String, Object> r = new HashMap<>();
+ r.put("region", regionState.getRegion().getEncodedName());
+ r.put("table", regionState.getRegion().getTable().getNameAsString());
+ r.put("state", regionState.getState());
+ r.put("server", regionState.getServerName());
+ r.put("startTime", regionState.getStamp());
+ r.put("duration", regionState.getRitDuration());
+ rits.add(r);
+ }
+ %>
+ <%= GSON.toJson(map) %>
+<% } else { %>
+<div class="container-fluid content">
+ <div class="row">
+ <p>
+ <%
+ if (filter.equals("region")) {
+ for (RegionState regionState : rit) { %>
+ <%= regionState.getRegion().getEncodedName() %><br>
+ <% }
+ } else { %>
+ "Not a valid filter"
+ <% } %>
+ </p>
+ </div>
+</div>
+<% } %>