blob: 16e6357157383d32695a5fa62bd2c15dee6fe813 [file] [log] [blame]
/**
* 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 com.alibaba.jstorm.metric;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import com.codahale.metrics.Gauge;
public class MetricJstack implements Gauge<String> {
private String getTaskName(long id, String name) {
if (name == null) {
return Long.toString(id);
}
return id + " (" + name + ")";
}
public String dumpThread() throws Exception {
StringBuilder writer = new StringBuilder();
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
boolean contention = threadMXBean.isThreadContentionMonitoringEnabled();
long[] threadIds = threadMXBean.getAllThreadIds();
writer.append(threadIds.length + " active threads:");
for (long tid : threadIds) {
writer.append(tid).append(" ");
}
writer.append("\n");
long[] deadLockTids = threadMXBean.findDeadlockedThreads();
if (deadLockTids != null) {
writer.append(threadIds.length + " deadlocked threads:");
for (long tid : deadLockTids) {
writer.append(tid).append(" ");
}
writer.append("\n");
}
long[] deadLockMonitorTids = threadMXBean.findMonitorDeadlockedThreads();
if (deadLockMonitorTids != null) {
writer.append(threadIds.length + " deadlocked monitor threads:");
for (long tid : deadLockMonitorTids) {
writer.append(tid).append(" ");
}
writer.append("\n");
}
for (long tid : threadIds) {
ThreadInfo info = threadMXBean.getThreadInfo(tid, Integer.MAX_VALUE);
if (info == null) {
writer.append(" Inactive").append("\n");
continue;
}
writer.append("Thread " + getTaskName(info.getThreadId(), info.getThreadName()) + ":").append("\n");
Thread.State state = info.getThreadState();
writer.append(" State: " + state).append("\n");
writer.append(" Blocked count: " + info.getBlockedCount()).append("\n");
writer.append(" Waited count: " + info.getWaitedCount()).append("\n");
writer.append(" Cpu time:").append(threadMXBean.getThreadCpuTime(tid) / 1000000).append("ms").append("\n");
writer.append(" User time:").append(threadMXBean.getThreadUserTime(tid) / 1000000).append("ms").append("\n");
if (contention) {
writer.append(" Blocked time: " + info.getBlockedTime()).append("\n");
writer.append(" Waited time: " + info.getWaitedTime()).append("\n");
}
if (state == Thread.State.WAITING) {
writer.append(" Waiting on " + info.getLockName()).append("\n");
} else if (state == Thread.State.BLOCKED) {
writer.append(" Blocked on " + info.getLockName()).append("\n");
writer.append(" Blocked by " + getTaskName(info.getLockOwnerId(), info.getLockOwnerName())).append("\n");
}
}
for (long tid : threadIds) {
ThreadInfo info = threadMXBean.getThreadInfo(tid, Integer.MAX_VALUE);
if (info == null) {
writer.append(" Inactive").append("\n");
continue;
}
writer.append("Thread " + getTaskName(info.getThreadId(), info.getThreadName()) + ": Stack").append("\n");
for (StackTraceElement frame : info.getStackTrace()) {
writer.append(" " + frame.toString()).append("\n");
}
}
return writer.toString();
}
@Override
public String getValue() {
try {
return dumpThread();
} catch (Exception e) {
return "Failed to get jstack thread info";
}
}
}