diff --git common/src/java/org/apache/hive/http/HttpServer.java common/src/java/org/apache/hive/http/HttpServer.java index 68730af..9e23b11 100644 --- common/src/java/org/apache/hive/http/HttpServer.java +++ common/src/java/org/apache/hive/http/HttpServer.java @@ -372,6 +372,7 @@ void initializeWebServer(Builder b) { addServlet("jmx", "/jmx", JMXJsonServlet.class); addServlet("conf", "/conf", ConfServlet.class); + addServlet("stacks", "/stacks", StackServlet.class); ServletContextHandler staticCtx = new ServletContextHandler(contexts, "/static"); diff --git common/src/java/org/apache/hive/http/StackServlet.java common/src/java/org/apache/hive/http/StackServlet.java new file mode 100644 index 0000000..610b391 --- /dev/null +++ common/src/java/org/apache/hive/http/StackServlet.java @@ -0,0 +1,103 @@ +/** + * 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. + */ +package org.apache.hive.http; + +import java.io.IOException; +import java.io.PrintStream; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * A servlet to print out the current stack traces. + */ +public class StackServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private static ThreadMXBean threadBean = + ManagementFactory.getThreadMXBean(); + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (!HttpServer.isInstrumentationAccessAllowed(getServletContext(), + request, response)) { + return; + } + response.setContentType("text/plain; charset=UTF-8"); + try (PrintStream out = new PrintStream( + response.getOutputStream(), false, "UTF-8")) { + printThreadInfo(out, ""); + } + } + + /** + * Print all of the thread's information and stack traces. + * + * @param stream the stream to + * @param title a string title for the stack trace + */ + private synchronized void printThreadInfo( + PrintStream stream, String title) { + final int STACK_DEPTH = 20; + boolean contention = threadBean.isThreadContentionMonitoringEnabled(); + long[] threadIds = threadBean.getAllThreadIds(); + stream.println("Process Thread Dump: " + title); + stream.println(threadIds.length + " active threads"); + for (long tid : threadIds) { + ThreadInfo info = threadBean.getThreadInfo(tid, STACK_DEPTH); + if (info == null) { + stream.println(" Inactive"); + continue; + } + stream.println("Thread " + + getTaskName(info.getThreadId(), info.getThreadName()) + ":"); + Thread.State state = info.getThreadState(); + stream.println(" State: " + state); + stream.println(" Blocked count: " + info.getBlockedCount()); + stream.println(" Wtaited count: " + info.getWaitedCount()); + if (contention) { + stream.println(" Blocked time: " + info.getBlockedTime()); + stream.println(" Waited time: " + info.getWaitedTime()); + } + if (state == Thread.State.WAITING) { + stream.println(" Waiting on " + info.getLockName()); + } else if (state == Thread.State.BLOCKED) { + stream.println(" Blocked on " + info.getLockName()); + stream.println(" Blocked by " + + getTaskName(info.getLockOwnerId(), info.getLockOwnerName())); + } + stream.println(" Stack:"); + for (StackTraceElement frame : info.getStackTrace()) { + stream.println(" " + frame.toString()); + } + } + stream.flush(); + } + + private String getTaskName(long id, String name) { + if (name == null) { + return Long.toString(id); + } + return id + " (" + name + ")"; + } +} diff --git service/src/resources/hive-webapps/hiveserver2/hiveserver2.jsp service/src/resources/hive-webapps/hiveserver2/hiveserver2.jsp index 4fad63c..0b437dd 100644 --- service/src/resources/hive-webapps/hiveserver2/hiveserver2.jsp +++ service/src/resources/hive-webapps/hiveserver2/hiveserver2.jsp @@ -70,6 +70,7 @@ SessionManager sessionManager =
  • Local logs
  • Metrics Dump
  • Hive Configuration
  • +
  • Stack Trace