org.gridkit.jvmtool.cmd.MxDumpCmd Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mxdump Show documentation
Show all versions of mxdump Show documentation
MBean to JSON dump command for Swiss Java Knife (SJK) tool
/**
* Copyright 2013 Alexey Ragozin
*
* Licensed 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 org.gridkit.jvmtool.cmd;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.Set;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeMBeanException;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.TabularData;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.gridkit.jvmtool.JmxConnectionInfo;
import org.gridkit.jvmtool.cli.CommandLauncher;
import org.gridkit.jvmtool.cli.CommandLauncher.CmdRef;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParametersDelegate;
/**
* MBean to JSON dump.
*/
public class MxDumpCmd implements CmdRef {
@Override
public String getCommandName() {
return "mxdump";
}
@Override
public Runnable newCommand(CommandLauncher host) {
return new MxDump(host);
}
public static class MxDump implements Runnable {
@ParametersDelegate
private CommandLauncher host;
@Parameter(names = {"-q", "--query"}, description = "Query to filter MBeans")
private String query;
@ParametersDelegate
private JmxConnectionInfo conn;
public MxDump(CommandLauncher host) {
this.host = host;
this.conn = new JmxConnectionInfo(host);
}
@Override
public void run() {
try {
ObjectName q = null;
if (query != null) {
q = new ObjectName(query);
}
MBeanServerConnection jmx = conn.getMServer();
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator jg = jsonFactory.createJsonGenerator(System.out);
jg.useDefaultPrettyPrinter();
jg.writeStartObject();
listBeans(q, jg, jmx);
jg.writeEndObject();
jg.close();
System.out.println();
System.out.flush();
} catch (Exception e) {
host.fail(e.toString());
}
}
private static void listBeans(ObjectName query, JsonGenerator jg, MBeanServerConnection mBeanServer) throws Exception {
Set names = null;
names = mBeanServer.queryNames(query, null);
jg.writeArrayFieldStart("beans");
Iterator it = names.iterator();
while (it.hasNext()) {
ObjectName oname = it.next();
MBeanInfo minfo;
String code = "";
minfo = mBeanServer.getMBeanInfo(oname);
code = minfo.getClassName();
String prs = "";
if ("org.apache.commons.modeler.BaseModelMBean".equals(code)) {
prs = "modelerType";
code = (String) mBeanServer.getAttribute(oname, prs);
}
jg.writeStartObject();
jg.writeStringField("name", oname.toString());
jg.writeStringField("modelerType", code);
MBeanAttributeInfo attrs[] = minfo.getAttributes();
for (int i = 0; i < attrs.length; i++) {
writeAttribute(mBeanServer, jg, oname, attrs[i]);
}
jg.writeEndObject();
}
jg.writeEndArray();
}
private static void writeAttribute(MBeanServerConnection mBeanServer, JsonGenerator jg, ObjectName oname, MBeanAttributeInfo attr) throws IOException {
if (!attr.isReadable()) {
return;
}
String attName = attr.getName();
if ("modelerType".equals(attName)) {
return;
}
if (attName.indexOf("=") >= 0 || attName.indexOf(":") >= 0
|| attName.indexOf(" ") >= 0) {
return;
}
Object value = null;
try {
value = mBeanServer.getAttribute(oname, attName);
} catch (AttributeNotFoundException e) {
//Ignored the attribute was not found, which should never happen because the bean
//just told us that it has this attribute, but if this happens just don't output
//the attribute.
return;
} catch (MBeanException e) {
//The code inside the attribute getter threw an exception so log it, and
// skip outputting the attribute
error("getting attribute "+attName+" of "+oname+" threw an exception", e);
return;
} catch (RuntimeMBeanException e) {
// The code inside the attribute getter threw an exception, so we skip
// outputting the attribute. We will log the exception in certain cases,
// but suppress the log message in others. See OPSAPS-5449 for more info.
if (!(e.getCause() instanceof UnsupportedOperationException)) {
error("getting attribute " + attName + " of " + oname + " threw " +
"an exception", e);
}
return;
} catch (RuntimeException e) {
//For some reason even with an MBeanException available to them Runtime exceptions
//can still find their way through, so treat them the same as MBeanException
error("getting attribute "+attName+" of "+oname+" threw an exception", e);
return;
} catch (ReflectionException e) {
//This happens when the code inside the JMX bean (setter?? from the java docs)
//threw an exception, so log it and skip outputting the attribute
error("getting attribute "+attName+" of "+oname+" threw an exception", e);
return;
} catch (InstanceNotFoundException e) {
//Ignored the mbean itself was not found, which should never happen because we
//just accessed it (perhaps something unregistered in-between) but if this
//happens just don't output the attribute.
return;
}
writeAttribute(jg, attName, value);
}
private static void error(String string, Throwable e) {
System.err.print(string);
e.printStackTrace(System.err);
}
private static void writeAttribute(JsonGenerator jg, String attName, Object value) throws IOException {
jg.writeFieldName(attName);
writeObject(jg, value);
}
private static void writeObject(JsonGenerator jg, Object value) throws IOException {
if(value == null) {
jg.writeNull();
} else {
Class> c = value.getClass();
if (c.isArray()) {
jg.writeStartArray();
int len = Array.getLength(value);
for (int j = 0; j < len; j++) {
Object item = Array.get(value, j);
writeObject(jg, item);
}
jg.writeEndArray();
} else if(value instanceof Number) {
Number n = (Number)value;
jg.writeNumber(n.toString());
} else if(value instanceof Boolean) {
Boolean b = (Boolean)value;
jg.writeBoolean(b);
} else if(value instanceof CompositeData) {
CompositeData cds = (CompositeData)value;
CompositeType comp = cds.getCompositeType();
Set keys = comp.keySet();
jg.writeStartObject();
for(String key: keys) {
writeAttribute(jg, key, cds.get(key));
}
jg.writeEndObject();
} else if(value instanceof TabularData) {
TabularData tds = (TabularData)value;
jg.writeStartArray();
for(Object entry : tds.values()) {
writeObject(jg, entry);
}
jg.writeEndArray();
} else {
jg.writeString(value.toString());
}
}
}
}
}