/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
*/
package com.caucho.admin.action;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeType;
import com.caucho.config.ConfigException;
import com.caucho.jmx.Jmx;
import com.caucho.util.Alarm;
import com.caucho.util.QDate;
public class JmxDumpAction extends AbstractJmxAction implements AdminAction
{
public static void main(String args[]) throws Exception
{
System.out.println(new JmxDumpAction().execute());
}
public String execute()
throws ConfigException, JMException, ClassNotFoundException
{
MBeanServer server = Jmx.getMBeanServer();
if (server == null)
server = ManagementFactory.getPlatformMBeanServer();
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append("\"create_time\": \""
+ new Date(Alarm.getCurrentTime()) + "\"\n");
if (server != null) {
sb.append(", \"jmx\": {\n");
fillServer(sb, server);
sb.append("\n}");
}
sb.append("\n}");
return sb.toString();
}
private void fillServer(StringBuilder sb, MBeanServer server)
{
Set<ObjectName> beans = new HashSet<ObjectName>();
//Set<ObjectName> objectNames = server.queryNames(new ObjectName("java.lang:type=Runtime"), null);
ArrayList<ObjectName> objectNames = new ArrayList<ObjectName>();
objectNames.addAll(server.queryNames(ObjectName.WILDCARD, null));
Collections.sort(objectNames);
boolean isFirst = true;
for (ObjectName objectName : objectNames) {
if (beans.contains(objectName))
continue;
beans.add(objectName);
if (! isFirst)
sb.append(",\n");
isFirst = false;
sb.append("\"");
escapeString(sb, String.valueOf(objectName));
sb.append("\" : {\n");
dumpMBean(sb, server, objectName);
sb.append("\n}");
}
}
private void dumpMBean(StringBuilder sb,
MBeanServer server,
ObjectName objectName)
{
MBeanAttributeInfo []attributes = null;
try {
attributes = server.getMBeanInfo(objectName).getAttributes();
} catch (Exception e) {
sb.append("\"mbean_exception\": \"" + e + "\"\n");
return;
}
boolean isFirst = true;
for (MBeanAttributeInfo attribute : attributes) {
if (! isFirst)
sb.append(",\n");
isFirst = false;
Object value = null;
try {
value = server.getAttribute(objectName, attribute.getName());
} catch (Throwable e) {
value = e;
}
dumpNameValue(sb, attribute.getName(), value, " ");
}
}
private void dumpNameValue(StringBuilder sb,
String name,
Object value, String padding)
{
sb.append(padding);
sb.append("\"");
escapeString(sb, name);
sb.append("\"");
sb.append(": ");
dumpValue(sb, value, padding);
}
private void dumpValue(StringBuilder sb, Object value, String padding)
{
if (value == null) {
sb.append("null");
} else if (value instanceof Object[]) {
Object[] values = (Object[]) value;
sb.append("[");
boolean isFirst = true;
for (Object v : values) {
if (! isFirst)
sb.append(",");
isFirst = false;
sb.append("\n" + padding + " ");
dumpValue(sb, v, padding + " ");
}
sb.append("\n" + padding + "]");
} else if (value instanceof CompositeData) {
CompositeData data = (CompositeData) value;
CompositeType type = data.getCompositeType();
sb.append(" {\n");
sb.append(padding);
sb.append(" \"java_class\": \"" + type.getTypeName() + "\"");
for (String key : type.keySet()) {
sb.append(",\n");
dumpNameValue(sb, key, data.get(key), padding + " ");
}
sb.append("\n" + padding + "}");
// } else if (value instanceof TabularData) {
// TabularData data = (TabularData) value;
// TabularType type = data.getTabularType();
// List<String> names = type.getIndexNames();
// dump.append(type.getTypeName());
// dump.append(" {\n");
// for(String name : names) {
// dump.append(name);
// //dumpNameValue(name, data.get(name), dump, padding + " ");
// }
// dump.append(padding);
// dump.append("}\n");
} else if (value instanceof Map) {
Map<Object, Object> data = (Map<Object, Object>) value;
sb.append("{\n");
sb.append(padding);
sb.append(" \"java_class\":\"" + value.getClass().getName() + "\"");
for(Map.Entry<Object, Object> entry : data.entrySet()) {
sb.append(",\n");
dumpNameValue(sb, entry.getKey().toString(), entry.getValue(),
padding + " ");
}
sb.append("\n" + padding);
sb.append("}");
} else if (value instanceof List) {
List<Object> values = (List<Object>) value;
sb.append("[\n");
boolean isFirst = true;
for (Object v : values) {
if (! isFirst) {
sb.append(",\n");
}
isFirst = false;
sb.append(padding + " ");
dumpValue(sb, v, padding + " ");
}
sb.append(padding);
sb.append("]");
} else if (value instanceof Throwable) {
Throwable e = (Throwable) value;
if (e instanceof UnsupportedOperationException) {
sb.append("\"Not supported\"");
} else {
Throwable cause = e.getCause();
if (cause != null) {
dumpValue(sb, cause, padding);
} else {
sb.append("\"" + e + "\"");
}
}
} else if (value instanceof Number) {
sb.append(value);
} else if (value instanceof Boolean) {
sb.append(value);
} else if (value instanceof Date) {
sb.append("\"" + QDate.formatISO8601(((Date) value).getTime()) + "\"");
} else {
sb.append("\"");
escapeString(sb, String.valueOf(value));
sb.append("\"");
}
}
private void escapeString(StringBuilder sb, String value)
{
int len = value.length();
for (int i = 0; i < len; i++) {
char ch = value.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
default:
sb.append(ch);
break;
}
}
}
}