/*
 * 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.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 java.util.logging.LogManager;
import java.util.logging.LoggingMXBean;

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 org.apache.juli.logging.Log log=
        org.apache.juli.logging.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 LoggingMXBean loggingMXBean =
        LogManager.getLoggingMXBean();
    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();
    }
}
