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;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.hbase.ipc.CallQueueInfo;
030import org.apache.hadoop.hbase.monitoring.StateDumpServlet;
031import org.apache.hadoop.hbase.monitoring.TaskMonitor;
032import org.apache.hadoop.hbase.util.LogMonitoring;
033import org.apache.hadoop.hbase.util.Threads;
034import org.apache.yetus.audience.InterfaceAudience;
035
036@InterfaceAudience.Private
037public class RSDumpServlet extends StateDumpServlet {
038  private static final long serialVersionUID = 1L;
039  private static final String LINE =
040    "===========================================================";
041
042  @Override
043  public void doGet(HttpServletRequest request, HttpServletResponse response)
044      throws IOException {
045    HRegionServer hrs = (HRegionServer)getServletContext().getAttribute(
046        HRegionServer.REGIONSERVER);
047    assert hrs != null : "No RS in context!";
048
049    response.setContentType("text/plain");
050
051    if (!hrs.isOnline()) {
052      response.getWriter().write("The RegionServer is initializing!");
053      response.getWriter().close();
054      return;
055    }
056
057    OutputStream os = response.getOutputStream();
058    try (PrintWriter out = new PrintWriter(os)) {
059
060      out.println("RegionServer status for " + hrs.getServerName()
061        + " as of " + new Date());
062
063      out.println("\n\nVersion Info:");
064      out.println(LINE);
065      dumpVersionInfo(out);
066
067      out.println("\n\nTasks:");
068      out.println(LINE);
069      TaskMonitor.get().dumpAsText(out);
070
071      out.println("\n\nRowLocks:");
072      out.println(LINE);
073      dumpRowLock(hrs, out);
074
075      out.println("\n\nExecutors:");
076      out.println(LINE);
077      dumpExecutors(hrs.getExecutorService(), out);
078
079      out.println("\n\nStacks:");
080      out.println(LINE);
081      PrintStream ps = new PrintStream(response.getOutputStream(), false, "UTF-8");
082      Threads.printThreadInfo(ps, "");
083      ps.flush();
084
085      out.println("\n\nRS Configuration:");
086      out.println(LINE);
087      Configuration conf = hrs.getConfiguration();
088      out.flush();
089      conf.writeXml(os);
090      os.flush();
091
092      out.println("\n\nLogs");
093      out.println(LINE);
094      long tailKb = getTailKbParam(request);
095      LogMonitoring.dumpTailOfLogs(out, tailKb);
096
097      out.println("\n\nRS Queue:");
098      out.println(LINE);
099      if (isShowQueueDump(conf)) {
100        dumpQueue(hrs, out);
101      }
102
103      out.println("\n\nCall Queue Summary:");
104      out.println(LINE);
105      dumpCallQueues(hrs, out);
106
107      out.flush();
108    }
109  }
110
111  public static void dumpRowLock(HRegionServer hrs, PrintWriter out) {
112    StringBuilder sb = new StringBuilder();
113    for (Region region : hrs.getRegions()) {
114      HRegion hRegion = (HRegion)region;
115      if (hRegion.getLockedRows().size() > 0) {
116        for (HRegion.RowLockContext rowLockContext : hRegion.getLockedRows().values()) {
117          sb.setLength(0);
118          sb.append(hRegion.getTableDescriptor().getTableName()).append(",")
119            .append(hRegion.getRegionInfo().getEncodedName()).append(",");
120          sb.append(rowLockContext.toString());
121          out.println(sb.toString());
122        }
123      }
124    }
125  }
126
127  public static void dumpQueue(HRegionServer hrs, PrintWriter out)
128      throws IOException {
129    if (hrs.compactSplitThread != null) {
130      // 1. Print out Compaction/Split Queue
131      out.println("Compaction/Split Queue summary: "
132          + hrs.compactSplitThread.toString() );
133      out.println(hrs.compactSplitThread.dumpQueue());
134    }
135
136    if (hrs.getMemStoreFlusher() != null) {
137      // 2. Print out flush Queue
138      out.println("\nFlush Queue summary: " + hrs.getMemStoreFlusher().toString());
139      out.println(hrs.getMemStoreFlusher().dumpQueue());
140    }
141  }
142
143
144  public static void dumpCallQueues(HRegionServer hrs, PrintWriter out) {
145    CallQueueInfo callQueueInfo = hrs.rpcServices.rpcServer.getScheduler().getCallQueueInfo();
146
147    for(String queueName: callQueueInfo.getCallQueueNames()) {
148
149      out.println("\nQueue Name: " + queueName);
150
151      long totalCallCount = 0L, totalCallSize = 0L;
152      for (String methodName: callQueueInfo.getCalledMethodNames(queueName)) {
153        long thisMethodCount, thisMethodSize;
154        thisMethodCount = callQueueInfo.getCallMethodCount(queueName, methodName);
155        thisMethodSize = callQueueInfo.getCallMethodSize(queueName, methodName);
156
157        out.println("Method in call: "+methodName);
158        out.println("Total call count for method: "+thisMethodCount);
159        out.println("Total call size for method (bytes): "+thisMethodSize);
160
161        totalCallCount += thisMethodCount;
162        totalCallSize += thisMethodSize;
163      }
164      out.println("Total call count for queue: "+totalCallCount);
165      out.println("Total call size for queue (bytes): "+totalCallSize);
166    }
167
168  }
169
170}