001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.regionserver;
020
021import java.io.IOException;
022import java.io.OutputStream;
023import java.io.PrintStream;
024import java.io.PrintWriter;
025import java.util.Date;
026import javax.servlet.http.HttpServletRequest;
027import javax.servlet.http.HttpServletResponse;
028
029import org.apache.hadoop.hbase.ipc.CallQueueInfo;
030import org.apache.yetus.audience.InterfaceAudience;
031import org.apache.hadoop.conf.Configuration;
032import org.apache.hadoop.hbase.monitoring.LogMonitoring;
033import org.apache.hadoop.hbase.monitoring.StateDumpServlet;
034import org.apache.hadoop.hbase.monitoring.TaskMonitor;
035import org.apache.hadoop.hbase.util.Threads;
036
037@InterfaceAudience.Private
038public class RSDumpServlet extends StateDumpServlet {
039  private static final long serialVersionUID = 1L;
040  private static final String LINE =
041    "===========================================================";
042
043  @Override
044  public void doGet(HttpServletRequest request, HttpServletResponse response)
045      throws IOException {
046    HRegionServer hrs = (HRegionServer)getServletContext().getAttribute(
047        HRegionServer.REGIONSERVER);
048    assert hrs != null : "No RS in context!";
049
050    response.setContentType("text/plain");
051
052    if (!hrs.isOnline()) {
053      response.getWriter().write("The RegionServer is initializing!");
054      response.getWriter().close();
055      return;
056    }
057
058    OutputStream os = response.getOutputStream();
059    try (PrintWriter out = new PrintWriter(os)) {
060
061      out.println("RegionServer status for " + hrs.getServerName()
062        + " as of " + new Date());
063
064      out.println("\n\nVersion Info:");
065      out.println(LINE);
066      dumpVersionInfo(out);
067
068      out.println("\n\nTasks:");
069      out.println(LINE);
070      TaskMonitor.get().dumpAsText(out);
071
072      out.println("\n\nRowLocks:");
073      out.println(LINE);
074      dumpRowLock(hrs, out);
075
076      out.println("\n\nExecutors:");
077      out.println(LINE);
078      dumpExecutors(hrs.getExecutorService(), out);
079
080      out.println("\n\nStacks:");
081      out.println(LINE);
082      PrintStream ps = new PrintStream(response.getOutputStream(), false, "UTF-8");
083      Threads.printThreadInfo(ps, "");
084      ps.flush();
085
086      out.println("\n\nRS Configuration:");
087      out.println(LINE);
088      Configuration conf = hrs.getConfiguration();
089      out.flush();
090      conf.writeXml(os);
091      os.flush();
092
093      out.println("\n\nLogs");
094      out.println(LINE);
095      long tailKb = getTailKbParam(request);
096      LogMonitoring.dumpTailOfLogs(out, tailKb);
097
098      out.println("\n\nRS Queue:");
099      out.println(LINE);
100      if (isShowQueueDump(conf)) {
101        dumpQueue(hrs, out);
102      }
103
104      out.println("\n\nCall Queue Summary:");
105      out.println(LINE);
106      dumpCallQueues(hrs, out);
107
108      out.flush();
109    }
110  }
111
112  public static void dumpRowLock(HRegionServer hrs, PrintWriter out) {
113    StringBuilder sb = new StringBuilder();
114    for (Region region : hrs.getRegions()) {
115      HRegion hRegion = (HRegion)region;
116      if (hRegion.getLockedRows().size() > 0) {
117        for (HRegion.RowLockContext rowLockContext : hRegion.getLockedRows().values()) {
118          sb.setLength(0);
119          sb.append(hRegion.getTableDescriptor().getTableName()).append(",")
120            .append(hRegion.getRegionInfo().getEncodedName()).append(",");
121          sb.append(rowLockContext.toString());
122          out.println(sb.toString());
123        }
124      }
125    }
126  }
127
128  public static void dumpQueue(HRegionServer hrs, PrintWriter out)
129      throws IOException {
130    if (hrs.compactSplitThread != null) {
131      // 1. Print out Compaction/Split Queue
132      out.println("Compaction/Split Queue summary: "
133          + hrs.compactSplitThread.toString() );
134      out.println(hrs.compactSplitThread.dumpQueue());
135    }
136
137    if (hrs.cacheFlusher != null) {
138      // 2. Print out flush Queue
139      out.println("\nFlush Queue summary: "
140          + hrs.cacheFlusher.toString());
141      out.println(hrs.cacheFlusher.dumpQueue());
142    }
143  }
144
145
146  public static void dumpCallQueues(HRegionServer hrs, PrintWriter out) {
147    CallQueueInfo callQueueInfo = hrs.rpcServices.rpcServer.getScheduler().getCallQueueInfo();
148
149    for(String queueName: callQueueInfo.getCallQueueNames()) {
150
151      out.println("\nQueue Name: " + queueName);
152
153      long totalCallCount = 0L, totalCallSize = 0L;
154      for (String methodName: callQueueInfo.getCalledMethodNames(queueName)) {
155        long thisMethodCount, thisMethodSize;
156        thisMethodCount = callQueueInfo.getCallMethodCount(queueName, methodName);
157        thisMethodSize = callQueueInfo.getCallMethodSize(queueName, methodName);
158
159        out.println("Method in call: "+methodName);
160        out.println("Total call count for method: "+thisMethodCount);
161        out.println("Total call size for method (bytes): "+thisMethodSize);
162
163        totalCallCount += thisMethodCount;
164        totalCallSize += thisMethodSize;
165      }
166      out.println("Total call count for queue: "+totalCallCount);
167      out.println("Total call size for queue (bytes): "+totalCallSize);
168    }
169
170  }
171
172}