init
This commit is contained in:
701
java/org/apache/tomcat/util/Diagnostics.java
Normal file
701
java/org/apache/tomcat/util/Diagnostics.java
Normal file
@@ -0,0 +1,701 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// XXX TODO: Source code line length
|
||||
// XXX TODO: More JavaDoc
|
||||
// XXX Optional: Add support for com.sun.management specific mbean
|
||||
// (http://docs.oracle.com/javase/7/docs/jre/api/management/extension/index.html)
|
||||
// XXX Optional: Wire additional public static methods implemented here
|
||||
// to the manager (think about manager access roles!)
|
||||
// setLoggerLevel(),
|
||||
// setVerboseClassLoading(),
|
||||
// setThreadContentionMonitoringEnabled(),
|
||||
// setThreadCpuTimeEnabled(),
|
||||
// resetPeakThreadCount(),
|
||||
// setVerboseGarbageCollection()
|
||||
// gc(),
|
||||
// resetPeakUsage(),
|
||||
// setUsageThreshold(),
|
||||
// setCollectionUsageThreshold()
|
||||
|
||||
package org.apache.tomcat.util;
|
||||
|
||||
import java.lang.management.ClassLoadingMXBean;
|
||||
import java.lang.management.CompilationMXBean;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.LockInfo;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.lang.management.MemoryManagerMXBean;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import java.lang.management.MonitorInfo;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.management.PlatformLoggingMXBean;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
public class Diagnostics {
|
||||
|
||||
private static final String PACKAGE = "org.apache.tomcat.util";
|
||||
private static final StringManager sm = StringManager.getManager(PACKAGE);
|
||||
|
||||
private static final String INDENT1 = " ";
|
||||
private static final String INDENT2 = "\t";
|
||||
private static final String INDENT3 = " ";
|
||||
private static final String CRLF = "\r\n";
|
||||
private static final String vminfoSystemProperty = "java.vm.info";
|
||||
|
||||
private static final Log log = LogFactory.getLog(Diagnostics.class);
|
||||
|
||||
private static final SimpleDateFormat timeformat =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
/* Some platform MBeans */
|
||||
private static final ClassLoadingMXBean classLoadingMXBean =
|
||||
ManagementFactory.getClassLoadingMXBean();
|
||||
private static final CompilationMXBean compilationMXBean =
|
||||
ManagementFactory.getCompilationMXBean();
|
||||
private static final OperatingSystemMXBean operatingSystemMXBean =
|
||||
ManagementFactory.getOperatingSystemMXBean();
|
||||
private static final RuntimeMXBean runtimeMXBean =
|
||||
ManagementFactory.getRuntimeMXBean();
|
||||
private static final ThreadMXBean threadMXBean =
|
||||
ManagementFactory.getThreadMXBean();
|
||||
|
||||
// XXX Not sure whether the following MBeans should better
|
||||
// be retrieved on demand, i.e. whether they can change
|
||||
// dynamically in the MBeanServer.
|
||||
private static final PlatformLoggingMXBean loggingMXBean =
|
||||
ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class);
|
||||
private static final MemoryMXBean memoryMXBean =
|
||||
ManagementFactory.getMemoryMXBean();
|
||||
private static final List<GarbageCollectorMXBean> garbageCollectorMXBeans =
|
||||
ManagementFactory.getGarbageCollectorMXBeans();
|
||||
private static final List<MemoryManagerMXBean> memoryManagerMXBeans =
|
||||
ManagementFactory.getMemoryManagerMXBeans();
|
||||
private static final List<MemoryPoolMXBean> memoryPoolMXBeans =
|
||||
ManagementFactory.getMemoryPoolMXBeans();
|
||||
|
||||
/**
|
||||
* Check whether thread contention monitoring is enabled.
|
||||
*
|
||||
* @return true if thread contention monitoring is enabled
|
||||
*/
|
||||
public static boolean isThreadContentionMonitoringEnabled() {
|
||||
return threadMXBean.isThreadContentionMonitoringEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable thread contention monitoring via the ThreadMxMXBean.
|
||||
*
|
||||
* @param enable whether to enable thread contention monitoring
|
||||
*/
|
||||
public static void setThreadContentionMonitoringEnabled(boolean enable) {
|
||||
threadMXBean.setThreadContentionMonitoringEnabled(enable);
|
||||
boolean checkValue = threadMXBean.isThreadContentionMonitoringEnabled();
|
||||
if (enable != checkValue) {
|
||||
log.error("Could not set threadContentionMonitoringEnabled to " +
|
||||
enable + ", got " + checkValue + " instead");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether thread cpu time measurement is enabled.
|
||||
*
|
||||
* @return true if thread cpu time measurement is enabled
|
||||
*/
|
||||
public static boolean isThreadCpuTimeEnabled() {
|
||||
return threadMXBean.isThreadCpuTimeEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable thread cpu time measurement via the ThreadMxMXBean.
|
||||
*
|
||||
* @param enable whether to enable thread cpu time measurement
|
||||
*/
|
||||
public static void setThreadCpuTimeEnabled(boolean enable) {
|
||||
threadMXBean.setThreadCpuTimeEnabled(enable);
|
||||
boolean checkValue = threadMXBean.isThreadCpuTimeEnabled();
|
||||
if (enable != checkValue) {
|
||||
log.error("Could not set threadCpuTimeEnabled to " + enable +
|
||||
", got " + checkValue + " instead");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset peak thread count in ThreadMXBean
|
||||
*/
|
||||
public static void resetPeakThreadCount() {
|
||||
threadMXBean.resetPeakThreadCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set verbose class loading
|
||||
*
|
||||
* @param verbose whether to enable verbose class loading
|
||||
*/
|
||||
public static void setVerboseClassLoading(boolean verbose) {
|
||||
classLoadingMXBean.setVerbose(verbose);
|
||||
boolean checkValue = classLoadingMXBean.isVerbose();
|
||||
if (verbose != checkValue) {
|
||||
log.error("Could not set verbose class loading to " + verbose +
|
||||
", got " + checkValue + " instead");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set logger level
|
||||
*
|
||||
* @param loggerName the name of the logger
|
||||
* @param levelName the level to set
|
||||
*/
|
||||
public static void setLoggerLevel(String loggerName, String levelName) {
|
||||
loggingMXBean.setLoggerLevel(loggerName, levelName);
|
||||
String checkValue = loggingMXBean.getLoggerLevel(loggerName);
|
||||
if (!checkValue.equals(levelName)) {
|
||||
log.error("Could not set logger level for logger '" +
|
||||
loggerName + "' to '" + levelName +
|
||||
"', got '" + checkValue + "' instead");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set verbose garbage collection logging
|
||||
*
|
||||
* @param verbose whether to enable verbose gc logging
|
||||
*/
|
||||
public static void setVerboseGarbageCollection(boolean verbose) {
|
||||
memoryMXBean.setVerbose(verbose);
|
||||
boolean checkValue = memoryMXBean.isVerbose();
|
||||
if (verbose != checkValue) {
|
||||
log.error("Could not set verbose garbage collection logging to " + verbose +
|
||||
", got " + checkValue + " instead");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate garbage collection via MX Bean
|
||||
*/
|
||||
public static void gc() {
|
||||
memoryMXBean.gc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset peak memory usage data in MemoryPoolMXBean
|
||||
*
|
||||
* @param name name of the MemoryPoolMXBean or "all"
|
||||
*/
|
||||
public static void resetPeakUsage(String name) {
|
||||
for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
|
||||
if (name.equals("all") || name.equals(mbean.getName())) {
|
||||
mbean.resetPeakUsage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set usage threshold in MemoryPoolMXBean
|
||||
*
|
||||
* @param name name of the MemoryPoolMXBean
|
||||
* @param threshold the threshold to set
|
||||
* @return true if setting the threshold succeeded
|
||||
*/
|
||||
public static boolean setUsageThreshold(String name, long threshold) {
|
||||
for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
|
||||
if (name.equals(mbean.getName())) {
|
||||
try {
|
||||
mbean.setUsageThreshold(threshold);
|
||||
return true;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// IGNORE
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set collection usage threshold in MemoryPoolMXBean
|
||||
*
|
||||
* @param name name of the MemoryPoolMXBean
|
||||
* @param threshold the collection threshold to set
|
||||
* @return true if setting the threshold succeeded
|
||||
*/
|
||||
public static boolean setCollectionUsageThreshold(String name, long threshold) {
|
||||
for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
|
||||
if (name.equals(mbean.getName())) {
|
||||
try {
|
||||
mbean.setCollectionUsageThreshold(threshold);
|
||||
return true;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// IGNORE
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the thread dump header for one thread.
|
||||
*
|
||||
* @param ti the ThreadInfo describing the thread
|
||||
* @return the formatted thread dump header
|
||||
*/
|
||||
private static String getThreadDumpHeader(ThreadInfo ti) {
|
||||
StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"");
|
||||
sb.append(" Id=" + ti.getThreadId());
|
||||
sb.append(" cpu=" + threadMXBean.getThreadCpuTime(ti.getThreadId()) +
|
||||
" ns");
|
||||
sb.append(" usr=" + threadMXBean.getThreadUserTime(ti.getThreadId()) +
|
||||
" ns");
|
||||
sb.append(" blocked " + ti.getBlockedCount() + " for " +
|
||||
ti.getBlockedTime() + " ms");
|
||||
sb.append(" waited " + ti.getWaitedCount() + " for " +
|
||||
ti.getWaitedTime() + " ms");
|
||||
|
||||
if (ti.isSuspended()) {
|
||||
sb.append(" (suspended)");
|
||||
}
|
||||
if (ti.isInNative()) {
|
||||
sb.append(" (running in native)");
|
||||
}
|
||||
sb.append(CRLF);
|
||||
sb.append(INDENT3 + "java.lang.Thread.State: " + ti.getThreadState());
|
||||
sb.append(CRLF);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the thread dump for one thread.
|
||||
*
|
||||
* @param ti the ThreadInfo describing the thread
|
||||
* @return the formatted thread dump
|
||||
*/
|
||||
private static String getThreadDump(ThreadInfo ti) {
|
||||
StringBuilder sb = new StringBuilder(getThreadDumpHeader(ti));
|
||||
for (LockInfo li : ti.getLockedSynchronizers()) {
|
||||
sb.append(INDENT2 + "locks " +
|
||||
li.toString() + CRLF);
|
||||
}
|
||||
boolean start = true;
|
||||
StackTraceElement[] stes = ti.getStackTrace();
|
||||
Object[] monitorDepths = new Object[stes.length];
|
||||
MonitorInfo[] mis = ti.getLockedMonitors();
|
||||
for (int i = 0; i < mis.length; i++) {
|
||||
monitorDepths[mis[i].getLockedStackDepth()] = mis[i];
|
||||
}
|
||||
for (int i = 0; i < stes.length; i++) {
|
||||
StackTraceElement ste = stes[i];
|
||||
sb.append(INDENT2 +
|
||||
"at " + ste.toString() + CRLF);
|
||||
if (start) {
|
||||
if (ti.getLockName() != null) {
|
||||
sb.append(INDENT2 + "- waiting on (a " +
|
||||
ti.getLockName() + ")");
|
||||
if (ti.getLockOwnerName() != null) {
|
||||
sb.append(" owned by " + ti.getLockOwnerName() +
|
||||
" Id=" + ti.getLockOwnerId());
|
||||
}
|
||||
sb.append(CRLF);
|
||||
}
|
||||
start = false;
|
||||
}
|
||||
if (monitorDepths[i] != null) {
|
||||
MonitorInfo mi = (MonitorInfo)monitorDepths[i];
|
||||
sb.append(INDENT2 +
|
||||
"- locked (a " + mi.toString() + ")"+
|
||||
" index " + mi.getLockedStackDepth() +
|
||||
" frame " + mi.getLockedStackFrame().toString());
|
||||
sb.append(CRLF);
|
||||
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the thread dump for a list of threads.
|
||||
*
|
||||
* @param tinfos the ThreadInfo array describing the thread list
|
||||
* @return the formatted thread dump
|
||||
*/
|
||||
private static String getThreadDump(ThreadInfo[] tinfos) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (ThreadInfo tinfo : tinfos) {
|
||||
sb.append(getThreadDump(tinfo));
|
||||
sb.append(CRLF);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any threads are deadlocked. If any, print
|
||||
* the thread dump for those threads.
|
||||
*
|
||||
* @return a deadlock message and the formatted thread dump
|
||||
* of the deadlocked threads
|
||||
*/
|
||||
public static String findDeadlock() {
|
||||
ThreadInfo[] tinfos = null;
|
||||
long[] ids = threadMXBean.findDeadlockedThreads();
|
||||
if (ids != null) {
|
||||
tinfos = threadMXBean.getThreadInfo(threadMXBean.findDeadlockedThreads(),
|
||||
true, true);
|
||||
if (tinfos != null) {
|
||||
StringBuilder sb =
|
||||
new StringBuilder("Deadlock found between the following threads:");
|
||||
sb.append(CRLF);
|
||||
sb.append(getThreadDump(tinfos));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a formatted JVM thread dump.
|
||||
* The default StringManager will be used.
|
||||
*
|
||||
* @return the formatted JVM thread dump
|
||||
*/
|
||||
public static String getThreadDump() {
|
||||
return getThreadDump(sm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a formatted JVM thread dump.
|
||||
* The given list of locales will be used
|
||||
* to retrieve a StringManager.
|
||||
*
|
||||
* @param requestedLocales list of locales to use
|
||||
* @return the formatted JVM thread dump
|
||||
*/
|
||||
public static String getThreadDump(Enumeration<Locale> requestedLocales) {
|
||||
return getThreadDump(
|
||||
StringManager.getManager(PACKAGE, requestedLocales));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a JVM thread dump formatted
|
||||
* using the given StringManager.
|
||||
*
|
||||
* @param requestedSm the StringManager to use
|
||||
* @return the formatted JVM thread dump
|
||||
*/
|
||||
public static String getThreadDump(StringManager requestedSm) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
synchronized(timeformat) {
|
||||
sb.append(timeformat.format(new Date()));
|
||||
}
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.threadDumpTitle"));
|
||||
sb.append(" ");
|
||||
sb.append(runtimeMXBean.getVmName());
|
||||
sb.append(" (");
|
||||
sb.append(runtimeMXBean.getVmVersion());
|
||||
String vminfo = System.getProperty(vminfoSystemProperty);
|
||||
if (vminfo != null) {
|
||||
sb.append(" " + vminfo);
|
||||
}
|
||||
sb.append("):" + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
ThreadInfo[] tis = threadMXBean.dumpAllThreads(true, true);
|
||||
sb.append(getThreadDump(tis));
|
||||
|
||||
sb.append(findDeadlock());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format contents of a MemoryUsage object.
|
||||
* @param name a text prefix used in formatting
|
||||
* @param usage the MemoryUsage object to format
|
||||
* @return the formatted contents
|
||||
*/
|
||||
private static String formatMemoryUsage(String name, MemoryUsage usage) {
|
||||
if (usage != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(INDENT1 + name + " init: " + usage.getInit() + CRLF);
|
||||
sb.append(INDENT1 + name + " used: " + usage.getUsed() + CRLF);
|
||||
sb.append(INDENT1 + name + " committed: " + usage.getCommitted() + CRLF);
|
||||
sb.append(INDENT1 + name + " max: " + usage.getMax() + CRLF);
|
||||
return sb.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a formatted JVM information text.
|
||||
* The default StringManager will be used.
|
||||
*
|
||||
* @return the formatted JVM information text
|
||||
*/
|
||||
public static String getVMInfo() {
|
||||
return getVMInfo(sm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a formatted JVM information text.
|
||||
* The given list of locales will be used
|
||||
* to retrieve a StringManager.
|
||||
*
|
||||
* @param requestedLocales list of locales to use
|
||||
* @return the formatted JVM information text
|
||||
*/
|
||||
public static String getVMInfo(Enumeration<Locale> requestedLocales) {
|
||||
return getVMInfo(StringManager.getManager(PACKAGE, requestedLocales));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a JVM information text formatted
|
||||
* using the given StringManager.
|
||||
*
|
||||
* @param requestedSm the StringManager to use
|
||||
* @return the formatted JVM information text
|
||||
*/
|
||||
public static String getVMInfo(StringManager requestedSm) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
synchronized(timeformat) {
|
||||
sb.append(timeformat.format(new Date()));
|
||||
}
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoRuntime"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "vmName: " + runtimeMXBean.getVmName() + CRLF);
|
||||
sb.append(INDENT1 + "vmVersion: " + runtimeMXBean.getVmVersion() + CRLF);
|
||||
sb.append(INDENT1 + "vmVendor: " + runtimeMXBean.getVmVendor() + CRLF);
|
||||
sb.append(INDENT1 + "specName: " + runtimeMXBean.getSpecName() + CRLF);
|
||||
sb.append(INDENT1 + "specVersion: " + runtimeMXBean.getSpecVersion() + CRLF);
|
||||
sb.append(INDENT1 + "specVendor: " + runtimeMXBean.getSpecVendor() + CRLF);
|
||||
sb.append(INDENT1 + "managementSpecVersion: " +
|
||||
runtimeMXBean.getManagementSpecVersion() + CRLF);
|
||||
sb.append(INDENT1 + "name: " + runtimeMXBean.getName() + CRLF);
|
||||
sb.append(INDENT1 + "startTime: " + runtimeMXBean.getStartTime() + CRLF);
|
||||
sb.append(INDENT1 + "uptime: " + runtimeMXBean.getUptime() + CRLF);
|
||||
sb.append(INDENT1 + "isBootClassPathSupported: " +
|
||||
runtimeMXBean.isBootClassPathSupported() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoOs"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "name: " + operatingSystemMXBean.getName() + CRLF);
|
||||
sb.append(INDENT1 + "version: " + operatingSystemMXBean.getVersion() + CRLF);
|
||||
sb.append(INDENT1 + "architecture: " + operatingSystemMXBean.getArch() + CRLF);
|
||||
sb.append(INDENT1 + "availableProcessors: " +
|
||||
operatingSystemMXBean.getAvailableProcessors() + CRLF);
|
||||
sb.append(INDENT1 + "systemLoadAverage: " +
|
||||
operatingSystemMXBean.getSystemLoadAverage() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoThreadMxBean"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "isCurrentThreadCpuTimeSupported: " +
|
||||
threadMXBean.isCurrentThreadCpuTimeSupported() + CRLF);
|
||||
sb.append(INDENT1 + "isThreadCpuTimeSupported: " +
|
||||
threadMXBean.isThreadCpuTimeSupported() + CRLF);
|
||||
sb.append(INDENT1 + "isThreadCpuTimeEnabled: " +
|
||||
threadMXBean.isThreadCpuTimeEnabled() + CRLF);
|
||||
sb.append(INDENT1 + "isObjectMonitorUsageSupported: " +
|
||||
threadMXBean.isObjectMonitorUsageSupported() + CRLF);
|
||||
sb.append(INDENT1 + "isSynchronizerUsageSupported: " +
|
||||
threadMXBean.isSynchronizerUsageSupported() + CRLF);
|
||||
sb.append(INDENT1 + "isThreadContentionMonitoringSupported: " +
|
||||
threadMXBean.isThreadContentionMonitoringSupported() + CRLF);
|
||||
sb.append(INDENT1 + "isThreadContentionMonitoringEnabled: " +
|
||||
threadMXBean.isThreadContentionMonitoringEnabled() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoThreadCounts"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "daemon: " + threadMXBean.getDaemonThreadCount() + CRLF);
|
||||
sb.append(INDENT1 + "total: " + threadMXBean.getThreadCount() + CRLF);
|
||||
sb.append(INDENT1 + "peak: " + threadMXBean.getPeakThreadCount() + CRLF);
|
||||
sb.append(INDENT1 + "totalStarted: " +
|
||||
threadMXBean.getTotalStartedThreadCount() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoStartup"));
|
||||
sb.append(":" + CRLF);
|
||||
for (String arg: runtimeMXBean.getInputArguments()) {
|
||||
sb.append(INDENT1 + arg + CRLF);
|
||||
}
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoPath"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "bootClassPath: " + runtimeMXBean.getBootClassPath() + CRLF);
|
||||
sb.append(INDENT1 + "classPath: " + runtimeMXBean.getClassPath() + CRLF);
|
||||
sb.append(INDENT1 + "libraryPath: " + runtimeMXBean.getLibraryPath() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoClassLoading"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "loaded: " +
|
||||
classLoadingMXBean.getLoadedClassCount() + CRLF);
|
||||
sb.append(INDENT1 + "unloaded: " +
|
||||
classLoadingMXBean.getUnloadedClassCount() + CRLF);
|
||||
sb.append(INDENT1 + "totalLoaded: " +
|
||||
classLoadingMXBean.getTotalLoadedClassCount() + CRLF);
|
||||
sb.append(INDENT1 + "isVerbose: " +
|
||||
classLoadingMXBean.isVerbose() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoClassCompilation"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "name: " + compilationMXBean.getName() + CRLF);
|
||||
sb.append(INDENT1 + "totalCompilationTime: " +
|
||||
compilationMXBean.getTotalCompilationTime() + CRLF);
|
||||
sb.append(INDENT1 + "isCompilationTimeMonitoringSupported: " +
|
||||
compilationMXBean.isCompilationTimeMonitoringSupported() + CRLF);
|
||||
sb.append(CRLF);
|
||||
|
||||
for (MemoryManagerMXBean mbean: memoryManagerMXBeans) {
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoMemoryManagers", mbean.getName()));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "isValid: " + mbean.isValid() + CRLF);
|
||||
sb.append(INDENT1 + "mbean.getMemoryPoolNames: " + CRLF);
|
||||
String[] names = mbean.getMemoryPoolNames();
|
||||
Arrays.sort(names);
|
||||
for (String name: names) {
|
||||
sb.append(INDENT2 + name + CRLF);
|
||||
}
|
||||
sb.append(CRLF);
|
||||
}
|
||||
|
||||
for (GarbageCollectorMXBean mbean: garbageCollectorMXBeans) {
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoGarbageCollectors", mbean.getName()));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "isValid: " + mbean.isValid() + CRLF);
|
||||
sb.append(INDENT1 + "mbean.getMemoryPoolNames: " + CRLF);
|
||||
String[] names = mbean.getMemoryPoolNames();
|
||||
Arrays.sort(names);
|
||||
for (String name: names) {
|
||||
sb.append(INDENT2 + name + CRLF);
|
||||
}
|
||||
sb.append(INDENT1 + "getCollectionCount: " + mbean.getCollectionCount() + CRLF);
|
||||
sb.append(INDENT1 + "getCollectionTime: " + mbean.getCollectionTime() + CRLF);
|
||||
sb.append(CRLF);
|
||||
}
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoMemory"));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "isVerbose: " + memoryMXBean.isVerbose() + CRLF);
|
||||
sb.append(INDENT1 + "getObjectPendingFinalizationCount: " + memoryMXBean.getObjectPendingFinalizationCount() + CRLF);
|
||||
sb.append(formatMemoryUsage("heap", memoryMXBean.getHeapMemoryUsage()));
|
||||
sb.append(formatMemoryUsage("non-heap", memoryMXBean.getNonHeapMemoryUsage()));
|
||||
sb.append(CRLF);
|
||||
|
||||
for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoMemoryPools", mbean.getName()));
|
||||
sb.append(":" + CRLF);
|
||||
sb.append(INDENT1 + "isValid: " + mbean.isValid() + CRLF);
|
||||
sb.append(INDENT1 + "getType: " + mbean.getType() + CRLF);
|
||||
sb.append(INDENT1 + "mbean.getMemoryManagerNames: " + CRLF);
|
||||
String[] names = mbean.getMemoryManagerNames();
|
||||
Arrays.sort(names);
|
||||
for (String name: names) {
|
||||
sb.append(INDENT2 + name + CRLF);
|
||||
}
|
||||
sb.append(INDENT1 + "isUsageThresholdSupported: " + mbean.isUsageThresholdSupported() + CRLF);
|
||||
try {
|
||||
sb.append(INDENT1 + "isUsageThresholdExceeded: " + mbean.isUsageThresholdExceeded() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
sb.append(INDENT1 + "isCollectionUsageThresholdSupported: " + mbean.isCollectionUsageThresholdSupported() + CRLF);
|
||||
try {
|
||||
sb.append(INDENT1 + "isCollectionUsageThresholdExceeded: " + mbean.isCollectionUsageThresholdExceeded() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
try {
|
||||
sb.append(INDENT1 + "getUsageThreshold: " + mbean.getUsageThreshold() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
try {
|
||||
sb.append(INDENT1 + "getUsageThresholdCount: " + mbean.getUsageThresholdCount() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
try {
|
||||
sb.append(INDENT1 + "getCollectionUsageThreshold: " + mbean.getCollectionUsageThreshold() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
try {
|
||||
sb.append(INDENT1 + "getCollectionUsageThresholdCount: " + mbean.getCollectionUsageThresholdCount() + CRLF);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
// IGNORE
|
||||
}
|
||||
sb.append(formatMemoryUsage("current", mbean.getUsage()));
|
||||
sb.append(formatMemoryUsage("collection", mbean.getCollectionUsage()));
|
||||
sb.append(formatMemoryUsage("peak", mbean.getPeakUsage()));
|
||||
sb.append(CRLF);
|
||||
}
|
||||
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoSystem"));
|
||||
sb.append(":" + CRLF);
|
||||
Map<String,String> props = runtimeMXBean.getSystemProperties();
|
||||
ArrayList<String> keys = new ArrayList<>(props.keySet());
|
||||
Collections.sort(keys);
|
||||
for (String prop: keys) {
|
||||
sb.append(INDENT1 + prop + ": " + props.get(prop) + CRLF);
|
||||
}
|
||||
sb.append(CRLF);
|
||||
|
||||
sb.append(requestedSm.getString("diagnostics.vmInfoLogger"));
|
||||
sb.append(":" + CRLF);
|
||||
List<String> loggers = loggingMXBean.getLoggerNames();
|
||||
Collections.sort(loggers);
|
||||
for (String logger: loggers) {
|
||||
sb.append(INDENT1 + logger +
|
||||
": level=" + loggingMXBean.getLoggerLevel(logger) +
|
||||
", parent=" + loggingMXBean.getParentLoggerName(logger) + CRLF);
|
||||
}
|
||||
sb.append(CRLF);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user