/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.plugins.jmx;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Set;
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.pluginapi.operation.OperationResult;
public class ThreadDataMeasurementComponent extends MBeanResourceComponent {
@Override
public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException,
Exception {
if ("threadDump".equals(name)) {
ThreadMXBean threadBean = getEmsBean().getProxy(ThreadMXBean.class);
long[] threadIds = threadBean.getAllThreadIds();
ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
OperationResult result = new OperationResult();
Configuration resultConfig = result.getComplexResults();
resultConfig.put(new PropertySimple("totalCount", threadBean.getThreadCount()));
PropertyList threadList = new PropertyList("threadList");
resultConfig.put(threadList);
for (ThreadInfo threadInfo : threadInfos) {
PropertyMap map = new PropertyMap("thread");
map.put(new PropertySimple("name", threadInfo.getThreadName()));
map.put(new PropertySimple("id", threadInfo.getThreadId()));
map.put(new PropertySimple("state", threadInfo.getThreadState().name()));
map.put(new PropertySimple("stack", getStringStackTrace(threadInfo.getStackTrace())));
threadList.add(map);
}
return result;
} else {
return super.invokeOperation(name, parameters);
}
}
@SuppressWarnings("unchecked")
@Override
protected void getValues(MeasurementReport report, Set requests, EmsBean bean) {
super.getValues(report, requests, bean);
for (MeasurementScheduleRequest request : (Set<MeasurementScheduleRequest>) requests) {
try {
if (request.getName().equals("SuspendedThreadCount")) {
log.debug("Getting suspended threads count value...");
report.addData(new MeasurementDataNumeric(request, getSuspendedThreadsCount(bean)));
} else if (request.getName().equals("DeadLockedThreadCount")) {
log.debug("Getting deadlocked threads count value...");
report.addData(new MeasurementDataNumeric(request, getDeadLockedThreadsCount(bean)));
}
} catch (Exception e) {
log.error("Failed to obtain measurement [" + request.getName() + "]. Cause: " + e.getMessage());
}
}
return;
}
private String getStringStackTrace(StackTraceElement[] st) {
StringBuilder buf = new StringBuilder(2000);
for (StackTraceElement e : st) {
buf.append(e.getClassName());
buf.append(".");
buf.append(e.getMethodName());
buf.append("(");
buf.append(e.getFileName());
buf.append(":");
buf.append(e.getLineNumber());
buf.append(")\n");
}
if (buf.length() > 2000) {
return buf.substring(0, 2000);
} else {
return buf.toString();
}
}
private Double getSuspendedThreadsCount(EmsBean bean) {
Double res = 0.0;
ThreadMXBean threadBean = bean.getProxy(ThreadMXBean.class);
long[] tids = threadBean.getAllThreadIds();
ThreadInfo[] tinfos = threadBean.getThreadInfo(tids, Integer.MAX_VALUE);
for (ThreadInfo ti : tinfos) {
if ((ti != null) && (ti.isSuspended()))
res++;
}
return res;
}
private Double getDeadLockedThreadsCount(EmsBean bean) {
ThreadMXBean threadBean = bean.getProxy(ThreadMXBean.class);
long[] tids = threadBean.findMonitorDeadlockedThreads();
if (tids == null) {
return 0.0;
} else {
return new Double(tids.length);
}
}
}