diff --git a/plugins/java/jmx/plugin/.classpath b/plugins/java/jmx/plugin/.classpath
new file mode 100644
index 00000000..fb501163
--- /dev/null
+++ b/plugins/java/jmx/plugin/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/plugins/java/jmx/plugin/.gitignore b/plugins/java/jmx/plugin/.gitignore
new file mode 100644
index 00000000..f00d6296
--- /dev/null
+++ b/plugins/java/jmx/plugin/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/.settings/
+*.class
diff --git a/plugins/java/jmx/plugin/.project b/plugins/java/jmx/plugin/.project
new file mode 100644
index 00000000..8fe5521c
--- /dev/null
+++ b/plugins/java/jmx/plugin/.project
@@ -0,0 +1,17 @@
+
+
+ plugin
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/plugins/java/jmx/plugin/META-INF/MANIFEST.MF b/plugins/java/jmx/plugin/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..bd17a1b5
--- /dev/null
+++ b/plugins/java/jmx/plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.8.1
+Created-By: 1.6.0_22-b04-307-10M3261 (Apple Inc.)
diff --git a/plugins/java/jmx/plugin/src/org/munin/Configuration.java b/plugins/java/jmx/plugin/src/org/munin/Configuration.java
new file mode 100644
index 00000000..5e4b5d8e
--- /dev/null
+++ b/plugins/java/jmx/plugin/src/org/munin/Configuration.java
@@ -0,0 +1,148 @@
+package org.munin;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class Configuration {
+ private Properties graph_properties = new Properties();
+ private Map fieldMap = new HashMap();
+ private List fields = new ArrayList();
+
+ public class FieldProperties extends Properties {
+ private static final long serialVersionUID = 1L;
+ private ObjectName jmxObjectName;
+ private String jmxAttributeName;
+ private String jmxAttributeKey;
+ private String fieldname;
+ private static final String JMXOBJECT = "jmxObjectName";
+ private static final String JMXATTRIBUTE = "jmxAttributeName";
+ private static final String JMXATTRIBUTEKEY = "jmxAttributeKey";
+
+ public FieldProperties(Configuration paramConfiguration,
+ String fieldname) {
+ this.fieldname = fieldname;
+ }
+
+ public String getJmxAttributeKey() {
+ return jmxAttributeKey;
+ }
+
+ public String getJmxAttributeName() {
+ return jmxAttributeName;
+ }
+
+ public ObjectName getJmxObjectName() {
+ return jmxObjectName;
+ }
+
+ public String toString() {
+ return fieldname;
+ }
+
+ public void set(String key, String value)
+ throws MalformedObjectNameException, NullPointerException {
+ if ("jmxObjectName".equals(key)) {
+ if (jmxObjectName != null)
+ throw new IllegalStateException(
+ "jmxObjectName already set for " + this);
+ jmxObjectName = new ObjectName(value);
+ } else if ("jmxAttributeName".equals(key)) {
+ if (jmxAttributeName != null)
+ throw new IllegalStateException(
+ "jmxAttributeName already set for " + this);
+ jmxAttributeName = value;
+ } else if ("jmxAttributeKey".equals(key)) {
+ if (jmxAttributeKey != null)
+ throw new IllegalStateException(
+ "jmxAttributeKey already set for " + this);
+ jmxAttributeKey = value;
+ } else {
+ put(key, value);
+ }
+ }
+
+ public void report(PrintStream out) {
+ for (Iterator it = entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ out.println(fieldname + '.' + entry.getKey() + " "
+ + entry.getValue());
+ }
+ }
+
+ public String getFieldname() {
+ return fieldname;
+ }
+ }
+
+ public static Configuration parse(String config_file) throws IOException,
+ MalformedObjectNameException, NullPointerException {
+ BufferedReader reader = new BufferedReader(new FileReader(config_file));
+ Configuration configuration = new Configuration();
+ try {
+ for (;;) {
+ String s = reader.readLine();
+ if (s == null)
+ break;
+ if ((!s.startsWith("%")) && (s.length() > 5)
+ && (!s.startsWith(" "))) {
+ configuration.parseString(s);
+ }
+ }
+ } finally {
+ reader.close();
+ }
+
+ return configuration;
+ }
+
+ private void parseString(String s) throws MalformedObjectNameException,
+ NullPointerException {
+ String[] nameval = s.split(" ", 2);
+ if (nameval[0].indexOf('.') > 0) {
+ String name = nameval[0];
+ String fieldname = name.substring(0, name.lastIndexOf('.'));
+ if (!fieldMap.containsKey(fieldname)) {
+ Configuration.FieldProperties field = new Configuration.FieldProperties(
+ this, fieldname);
+ fieldMap.put(fieldname, field);
+ fields.add(field);
+ }
+ Configuration.FieldProperties field = (Configuration.FieldProperties) fieldMap
+ .get(fieldname);
+ String key = name.substring(name.lastIndexOf('.') + 1);
+ field.set(key, nameval[1]);
+ } else {
+ graph_properties.put(nameval[0], nameval[1]);
+ }
+ }
+
+ public Properties getGraphProperties() {
+ return graph_properties;
+ }
+
+ public void report(PrintStream out) {
+ for (Iterator it = graph_properties.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ out.println(entry.getKey() + " " + entry.getValue());
+ }
+
+ for (Configuration.FieldProperties field : fields) {
+ field.report(out);
+ }
+ }
+
+ public List getFields() {
+ return fields;
+ }
+}
diff --git a/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java b/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java
new file mode 100644
index 00000000..0ac91905
--- /dev/null
+++ b/plugins/java/jmx/plugin/src/org/munin/JMXQuery.java
@@ -0,0 +1,228 @@
+package org.munin;
+
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class JMXQuery {
+ private static final String USERNAME_KEY = "username";
+ private static final String PASSWORD_KEY = "password";
+ public static final String USAGE = "Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL";
+ private String url;
+ private String username;
+ private String password;
+ private JMXConnector connector;
+ private MBeanServerConnection connection;
+ private Configuration config;
+
+ public JMXQuery(String url) {
+ this(url, null, null);
+ }
+
+ public JMXQuery(String url, String username, String password) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ private void connect() throws IOException {
+ Map environment = null;
+ if ((username != null) && (password != null)) {
+ environment = new HashMap();
+
+ environment.put("jmx.remote.credentials", new String[] { username,
+ password });
+ environment.put("username", username);
+ environment.put("password", password);
+ }
+
+ JMXServiceURL jmxUrl = new JMXServiceURL(url);
+ connector = JMXConnectorFactory.connect(jmxUrl, environment);
+ connection = connector.getMBeanServerConnection();
+ }
+
+ private void list() throws IOException, InstanceNotFoundException,
+ IntrospectionException, ReflectionException {
+ if (config == null) {
+ listAll();
+ } else {
+ listConfig();
+ }
+ }
+
+ private void listConfig() {
+ for (Configuration.FieldProperties field : config.getFields()) {
+ try {
+ Object value = connection.getAttribute(
+ field.getJmxObjectName(), field.getJmxAttributeName());
+ output(field.getFieldname(), value, field.getJmxAttributeKey());
+ } catch (Exception e) {
+ System.err.println("Fail to output " + field);
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void output(String name, Object attr, String key) {
+ if ((attr instanceof CompositeDataSupport)) {
+ CompositeDataSupport cds = (CompositeDataSupport) attr;
+ if (key == null) {
+ throw new IllegalArgumentException(
+ "Key is null for composed data " + name);
+ }
+ System.out.println(name + ".value " + format(cds.get(key)));
+ } else {
+ System.out.println(name + ".value " + format(attr));
+ }
+ }
+
+ private void output(String name, Object attr) {
+ CompositeDataSupport cds;
+ Iterator it;
+ if ((attr instanceof CompositeDataSupport)) {
+ cds = (CompositeDataSupport) attr;
+ for (it = cds.getCompositeType().keySet().iterator(); it.hasNext();) {
+ String key = it.next().toString();
+ System.out.println(name + "." + key + ".value "
+ + format(cds.get(key)));
+ }
+ } else {
+ System.out.println(name + ".value " + format(attr));
+ }
+ }
+
+ private void listAll() throws IOException, InstanceNotFoundException,
+ IntrospectionException, ReflectionException {
+ Set mbeans = connection.queryNames(null, null);
+ for (ObjectName name : mbeans) {
+ MBeanInfo info = connection.getMBeanInfo(name);
+ MBeanAttributeInfo[] attrs = info.getAttributes();
+ String[] attrNames = new String[attrs.length];
+ for (int i = 0; i < attrs.length; i++) {
+ attrNames[i] = attrs[i].getName();
+ }
+ try {
+ AttributeList attributes = connection.getAttributes(name,
+ attrNames);
+ for (Attribute attribute : attributes.asList()) {
+ output(name.getCanonicalName() + "%" + attribute.getName(),
+ attribute.getValue());
+ }
+ } catch (Exception e) {
+ System.err.println("error getting " + name + ":"
+ + e.getMessage());
+ }
+ }
+ }
+
+ private String format(Object value) {
+ if (value == null)
+ return null;
+ if ((value instanceof String))
+ return (String) value;
+ if ((value instanceof Number)) {
+ NumberFormat f = NumberFormat.getInstance();
+ f.setMaximumFractionDigits(2);
+ f.setGroupingUsed(false);
+ return f.format(value);
+ }
+ if ((value instanceof Object[])) {
+ return Integer.toString(Arrays.asList((Object[]) value).size());
+ }
+ return value.toString();
+ }
+
+ private void disconnect() throws IOException {
+ connector.close();
+ }
+
+ public static void main(String[] args) {
+ int arglen = args.length;
+ if (arglen < 1) {
+ System.err
+ .println("Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL");
+ System.exit(1);
+ }
+
+ String url = null;
+ String user = null;
+ String pass = null;
+ String config_file = null;
+ boolean toconfig = false;
+ for (int i = 0; i < arglen; i++) {
+ if (args[i].startsWith("--url=")) {
+ url = args[i].substring(6);
+ } else if (args[i].startsWith("--user=")) {
+ user = args[i].substring(7);
+ } else if (args[i].startsWith("--pass=")) {
+ pass = args[i].substring(7);
+ } else if (args[i].startsWith("--conf=")) {
+ config_file = args[i].substring(7);
+ } else if (args[i].equals("config")) {
+ toconfig = true;
+ }
+ }
+
+ if ((url == null) || ((user != null) && (pass == null))
+ || ((user == null) && (pass != null))
+ || ((config_file == null) && (toconfig))) {
+ System.err
+ .println("Usage of program is:\njava -cp jmxquery.jar org.munin.JMXQuery --url= [--user= --pass=] [--conf= [config]]\n, where is a JMX URL, for example: service:jmx:rmi:///jndi/rmi://HOST:PORT/jmxrmi\nWhen invoked with the config file (see examples folder) - operates as Munin plugin with the provided configuration\nWithout options just fetches all JMX attributes using provided URL");
+ System.exit(1);
+ }
+
+ if (toconfig) {
+ try {
+ Configuration.parse(config_file).report(System.out);
+ } catch (Exception e) {
+ System.err.println(e.getMessage() + " reading " + config_file);
+ System.exit(1);
+ }
+ } else {
+ JMXQuery query = new JMXQuery(url, user, pass);
+ try {
+ query.connect();
+ if (config_file != null) {
+ query.setConfig(Configuration.parse(config_file));
+ }
+ query.list();
+ } catch (Exception ex) {
+ System.err.println(ex.getMessage() + " querying " + url);
+ ex.printStackTrace();
+ System.exit(1);
+ } finally {
+ try {
+ query.disconnect();
+ } catch (IOException e) {
+ System.err.println(e.getMessage() + " closing " + url);
+ }
+ }
+ }
+ }
+
+ private void setConfig(Configuration configuration) {
+ config = configuration;
+ }
+
+ public Configuration getConfig() {
+ return config;
+ }
+}