mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
remove plugin in main munin distribution (jmx), and extract jmx2munin
This commit is contained in:
parent
7dbdcedaf0
commit
933f0ea70b
8
plugins/java/jmx2munin/.gitignore
vendored
Normal file
8
plugins/java/jmx2munin/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
.classpath
|
||||
.project
|
||||
.fatjar
|
||||
target
|
||||
eclipse
|
||||
old
|
||||
bin
|
79
plugins/java/jmx2munin/README.md
Normal file
79
plugins/java/jmx2munin/README.md
Normal file
@ -0,0 +1,79 @@
|
||||
# jmx2munin
|
||||
|
||||
The [jmx2munin](http://github.com/tcurdt/jmx2munin) project exposes JMX MBean attributes to [Munin](http://munin-monitoring.org/).
|
||||
Some of it's features:
|
||||
|
||||
* strictly complies to the plugin format
|
||||
* exposes composite types like Lists, Maps, Set as useful as possible
|
||||
* String values can be mapped to numbers
|
||||
|
||||
# How to use
|
||||
|
||||
This is what the Munin script will call. So you should test this first. Of course with your parameters. This example expose all Cassandra information to Munin.
|
||||
|
||||
java -jar jmx2munin.jar \
|
||||
-url service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi \
|
||||
-query "org.apache.cassandra.*:*"
|
||||
|
||||
The "url" parameters specifies the JMX URL, the query selects the MBeans (and optionally also the attributes) to expose.
|
||||
|
||||
java -jar jmx2munin.jar \
|
||||
-url service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi \
|
||||
-query "org.apache.cassandra.*:*" \
|
||||
-attribute org_apache_cassandra_db_storageservice_livenodes_size
|
||||
|
||||
The script that does the actual interaction with munin you can find in the contrib section. It's the one you should link in the your Munin plugin directory.
|
||||
|
||||
:/etc/munin/plugins$ ls -la cassandra_*
|
||||
lrwxrwxrwx 1 root root 37 2011-04-07 19:58 cassandra_nodes_in_cluster -> /usr/share/munin/plugins/jmx2munin.sh
|
||||
|
||||
In the plugin conf you point to the correct configuration
|
||||
|
||||
[cassandra_*]
|
||||
env.query org.apache.cassandra.*:*
|
||||
|
||||
[cassandra_nodes_in_cluster]
|
||||
env.config cassandra/nodes_in_cluster
|
||||
|
||||
A possible configuration could look like this
|
||||
|
||||
graph_title Number of Nodes in Cluster
|
||||
graph_vlabel org_apache_cassandra_db_storageservice_livenodes_size
|
||||
org_apache_cassandra_db_storageservice_livenodes_size.label number of nodes
|
||||
|
||||
The script will extract the attributes from the config and caches the JMX results to reduce the load when showing many values.
|
||||
|
||||
# More advanced
|
||||
|
||||
Sometimes it can be useful to track String values by mapping them into an enum as they really describe states. To find this possible candidates you can call:
|
||||
|
||||
java -jar jmx2munin.jar \
|
||||
-url service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi \
|
||||
-query "org.apache.cassandra.*:*" \
|
||||
list
|
||||
|
||||
It should output a list of possible candidates. This can now be turned into a enum configuration file:
|
||||
|
||||
[org.apache.cassandra.db.StorageService:OperationMode]
|
||||
0 = ^Normal
|
||||
1 = ^Client
|
||||
2 = ^Joining
|
||||
3 = ^Bootstrapping
|
||||
4 = ^Leaving
|
||||
5 = ^Decommissioned
|
||||
6 = ^Starting drain
|
||||
7 = ^Node is drained
|
||||
|
||||
Which you then can provide:
|
||||
|
||||
java -jar jmx2munin.jar \
|
||||
-url service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi \
|
||||
-query "org.apache.cassandra.*:*" \
|
||||
-enums /path/to/enums.cfg
|
||||
|
||||
Now matching values get replaced by their numerical representation. On the left needs to be a unique number on the right side is a regular expression. If a string cannot be matched according to the spec "U" for "undefined" will be returned.
|
||||
|
||||
# License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License")
|
||||
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
@ -0,0 +1,3 @@
|
||||
graph_title Number of Nodes in Cluster
|
||||
graph_vlabel org_apache_cassandra_db_storageservice_livenodes_size
|
||||
org_apache_cassandra_db_storageservice_livenodes_size.label number of nodes
|
55
plugins/java/jmx2munin/contrib/jmx2munin.sh
Normal file
55
plugins/java/jmx2munin/contrib/jmx2munin.sh
Normal file
@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# [cassandra_nodes_in_cluster]
|
||||
# env.config cassandra/nodes_in_cluster
|
||||
# env.query org.apache.cassandra.*:*
|
||||
|
||||
if [ -z "$MUNIN_LIBDIR" ]; then
|
||||
MUNIN_LIBDIR="`dirname $(dirname "$0")`"
|
||||
fi
|
||||
|
||||
if [ -f "$MUNIN_LIBDIR/plugins/plugin.sh" ]; then
|
||||
. $MUNIN_LIBDIR/plugins/plugin.sh
|
||||
fi
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
echo yes
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$url" ]; then
|
||||
# this is very common so make it a default
|
||||
url="service:jmx:rmi:///jndi/rmi://127.0.0.1:8080/jmxrmi"
|
||||
fi
|
||||
|
||||
if [ -z "$config" -o -z "$query" -o -z "$url" ]; then
|
||||
echo "Configuration needs attributes config, query and optinally url"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JMX2MUNIN_DIR="$MUNIN_LIBDIR/plugins"
|
||||
CONFIG="$JMX2MUNIN_DIR/jmx2munin.cfg/$config"
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
cat "$CONFIG"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
JAR="$JMX2MUNIN_DIR/jmx2munin.jar"
|
||||
CACHED="/tmp/jmx2munin"
|
||||
|
||||
if test ! -f $CACHED || test `find "$CACHED" -mmin +2`; then
|
||||
|
||||
java -jar "$JAR" \
|
||||
-url "$url" \
|
||||
-query "$query" \
|
||||
$ATTRIBUTES \
|
||||
> $CACHED
|
||||
|
||||
echo "cached.value `date +%s`" >> $CACHED
|
||||
fi
|
||||
|
||||
ATTRIBUTES=`awk '/\.label/ { gsub(/\.label/,""); print $1 }' $CONFIG`
|
||||
|
||||
for ATTRIBUTE in $ATTRIBUTES; do
|
||||
grep $ATTRIBUTE $CACHED
|
||||
done
|
121
plugins/java/jmx2munin/pom.xml
Normal file
121
plugins/java/jmx2munin/pom.xml
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.vafer</groupId>
|
||||
<artifactId>jmx2munin</artifactId>
|
||||
<name>jmx2munin</name>
|
||||
<version>1.0</version>
|
||||
<description>
|
||||
Munin plugin to access JMX information
|
||||
</description>
|
||||
<url>http://github.com/tcurdt/jmx2munin</url>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>tcurdt</id>
|
||||
<name>Torsten Curdt</name>
|
||||
<email>tcurdt at vafer.org</email>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License 2</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com:tcurdt/jmx2munin.git</connection>
|
||||
<developerConnection>scm:git:git://github.com:tcurdt/jmx2munin.git</developerConnection>
|
||||
<url>http://github.com/tcurdt/jmx2munin/tree/master</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.beust</groupId>
|
||||
<artifactId>jcommander</artifactId>
|
||||
<version>1.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkMode>never</forkMode>
|
||||
<includes>
|
||||
<include>**/*TestCase.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*</exclude>
|
||||
</excludes>
|
||||
<testFailureIgnore>true</testFailureIgnore>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>create-source-jar</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>com.beust:jcommander</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.vafer.jmx.munin.Munin</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,77 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public final class Enums {
|
||||
|
||||
private TreeMap<String, LinkedHashMap<Integer, Pattern>> sections = new TreeMap<String, LinkedHashMap<Integer, Pattern>>();
|
||||
|
||||
public boolean load(String filePath) throws IOException {
|
||||
BufferedReader input = null;
|
||||
LinkedHashMap<Integer, Pattern> section = new LinkedHashMap<Integer, Pattern>();
|
||||
try {
|
||||
input = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
|
||||
String line;
|
||||
int linenr = 0;
|
||||
while((line = input.readLine()) != null) {
|
||||
linenr += 1;
|
||||
line = line.trim();
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("[") && line.endsWith("]")) {
|
||||
// new section
|
||||
String id = line.substring(1, line.length() - 1);
|
||||
section = new LinkedHashMap<Integer, Pattern>();
|
||||
sections.put(id, section);
|
||||
} else {
|
||||
String[] pair = line.split("=");
|
||||
if (pair.length == 2) {
|
||||
Integer number = Integer.parseInt(pair[0].trim());
|
||||
Pattern pattern = Pattern.compile(pair[1].trim());
|
||||
if (section.put(number, pattern) != null) {
|
||||
System.err.println("Line " + linenr + ": previous definitions of " + number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String id(ObjectName beanName, String attributeName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(beanName.getDomain());
|
||||
sb.append('.');
|
||||
sb.append(beanName.getKeyProperty("type"));
|
||||
sb.append(':');
|
||||
sb.append(attributeName);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Number resolve(String id, String value) {
|
||||
LinkedHashMap<Integer, Pattern> section = sections.get(id);
|
||||
if (section == null) {
|
||||
return null;
|
||||
}
|
||||
for(Map.Entry<Integer, Pattern> entry : section.entrySet()) {
|
||||
if (entry.getValue().matcher(value).matches()) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public interface Filter {
|
||||
|
||||
public boolean include(ObjectName bean, String attribute);
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public final class ListOutput implements Output {
|
||||
|
||||
private final Set<String> seen = new HashSet<String>();
|
||||
|
||||
public void output(ObjectName beanName, String attributeName, Object value) {
|
||||
Value.flatten(beanName, attributeName, value, new Value.Listener() {
|
||||
public void value(ObjectName beanName, String attributeName, String value) {
|
||||
final String id = Enums.id(beanName, attributeName);
|
||||
if (!seen.contains(id)) {
|
||||
System.out.println("[" + id + "]");
|
||||
seen.add(id);
|
||||
}
|
||||
}
|
||||
public void value(ObjectName beanName, String attributeName, Number value) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public final class NoFilter implements Filter {
|
||||
|
||||
public boolean include(ObjectName bean, String attribute) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public interface Output {
|
||||
|
||||
public void output(ObjectName beanName, String attributeName, Object value);
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package org.vafer.jmx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.management.AttributeNotFoundException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.IntrospectionException;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectInstance;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
|
||||
public final class Query {
|
||||
|
||||
public void run(String url, String expression, Filter filter, Output output) throws IOException, MalformedObjectNameException, InstanceNotFoundException, ReflectionException, IntrospectionException, AttributeNotFoundException, MBeanException {
|
||||
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(url));
|
||||
MBeanServerConnection connection = connector.getMBeanServerConnection();
|
||||
final Collection<ObjectInstance> mbeans = connection.queryMBeans(new ObjectName(expression), null);
|
||||
|
||||
for(ObjectInstance mbean : mbeans) {
|
||||
final ObjectName mbeanName = mbean.getObjectName();
|
||||
final MBeanInfo mbeanInfo = connection.getMBeanInfo(mbeanName);
|
||||
final MBeanAttributeInfo[] attributes = mbeanInfo.getAttributes();
|
||||
for (final MBeanAttributeInfo attribute : attributes) {
|
||||
if (attribute.isReadable()) {
|
||||
if (filter.include(mbeanName, attribute.getName())) {
|
||||
final String attributeName = attribute.getName();
|
||||
try {
|
||||
output.output(
|
||||
mbean.getObjectName(),
|
||||
attributeName,
|
||||
connection.getAttribute(mbeanName, attributeName)
|
||||
);
|
||||
} catch(Exception e) {
|
||||
// System.err.println("Failed to read " + mbeanName + "." + attributeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
connector.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package org.vafer.jmx;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public final class Value {
|
||||
|
||||
public interface Listener {
|
||||
public void value(ObjectName beanName, String attributeName, String value);
|
||||
public void value(ObjectName beanName, String attributeName, Number value);
|
||||
}
|
||||
|
||||
public static void flatten(ObjectName beanName, String attributeName, Object value, Listener listener) {
|
||||
if (value instanceof Number) {
|
||||
|
||||
listener.value(beanName, attributeName, (Number) value);
|
||||
|
||||
} else if (value instanceof String) {
|
||||
|
||||
listener.value(beanName, attributeName, (String) value);
|
||||
|
||||
} else if (value instanceof Set) {
|
||||
|
||||
final Set set = (Set) value;
|
||||
flatten(beanName, attributeName + ".size", set.size(), listener);
|
||||
for(Object entry : set) {
|
||||
flatten(beanName, attributeName + "[" + entry + "]", 1, listener);
|
||||
}
|
||||
|
||||
} else if (value instanceof List) {
|
||||
|
||||
final List list = (List)value;
|
||||
listener.value(beanName, attributeName + ".size", list.size());
|
||||
for(int i = 0; i<list.size(); i++) {
|
||||
flatten(beanName, attributeName + "[" + i + "]", list.get(i), listener);
|
||||
}
|
||||
|
||||
} else if (value instanceof Map) {
|
||||
|
||||
final Map<?,?> map = (Map<?,?>) value;
|
||||
listener.value(beanName, attributeName + ".size", map.size());
|
||||
for(Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
flatten(beanName, attributeName + "[" + entry.getKey() + "]", entry.getValue(), listener);
|
||||
}
|
||||
|
||||
} else {
|
||||
// System.err.println("Failed to convert " + beanName + "." + attributeName);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package org.vafer.jmx.munin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.vafer.jmx.Enums;
|
||||
import org.vafer.jmx.Filter;
|
||||
import org.vafer.jmx.ListOutput;
|
||||
import org.vafer.jmx.NoFilter;
|
||||
import org.vafer.jmx.Query;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
|
||||
public final class Munin {
|
||||
|
||||
@Parameter(description = "")
|
||||
private List<String> args = new ArrayList<String>();
|
||||
|
||||
@Parameter(names = "-url", description = "jmx url", required = true)
|
||||
private String url;
|
||||
|
||||
@Parameter(names = "-query", description = "query expression", required = true)
|
||||
private String query;
|
||||
|
||||
@Parameter(names = "-enums", description = "file string to enum config")
|
||||
private String enumsPath;
|
||||
|
||||
@Parameter(names = "-attribute", description = "attributes to return")
|
||||
private List<String> attributes = new ArrayList<String>();
|
||||
|
||||
private void run() throws Exception {
|
||||
final Filter filter;
|
||||
if (attributes == null || attributes.isEmpty()) {
|
||||
filter = new NoFilter();
|
||||
} else {
|
||||
filter = new MuninAttributesFilter(attributes);
|
||||
}
|
||||
|
||||
final Enums enums = new Enums();
|
||||
if (enumsPath != null) {
|
||||
enums.load(enumsPath);
|
||||
}
|
||||
|
||||
final String cmd = args.toString().toLowerCase(Locale.US);
|
||||
if ("[list]".equals(cmd)) {
|
||||
new Query().run(url, query, filter, new ListOutput());
|
||||
} else {
|
||||
new Query().run(url, query, filter, new MuninOutput(enums));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Munin m = new Munin();
|
||||
|
||||
JCommander cli = new JCommander(m);
|
||||
try {
|
||||
cli.parse(args);
|
||||
} catch(Exception e) {
|
||||
cli.usage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
m.run();
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package org.vafer.jmx.munin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.vafer.jmx.Filter;
|
||||
|
||||
public final class MuninAttributesFilter implements Filter {
|
||||
|
||||
private final HashSet<String> attributes = new HashSet<String>();
|
||||
|
||||
public MuninAttributesFilter(List<String> pAttributes) {
|
||||
for (String attribute : pAttributes) {
|
||||
attributes.add(attribute.trim().replaceAll("_size$", ""));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean include(ObjectName bean, String attribute) {
|
||||
return attributes.contains(MuninOutput.attributeName(bean, attribute));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package org.vafer.jmx.munin;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.vafer.jmx.Enums;
|
||||
import org.vafer.jmx.Output;
|
||||
import org.vafer.jmx.Value;
|
||||
|
||||
public final class MuninOutput implements Output {
|
||||
|
||||
private final Enums enums;
|
||||
|
||||
public MuninOutput(Enums enums) {
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public static String attributeName(ObjectName bean, String attribute) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(fieldname(beanString(bean)));
|
||||
sb.append('_');
|
||||
sb.append(fieldname(attribute));
|
||||
return sb.toString().toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
private static String fieldname(String s) {
|
||||
return s.replaceAll("[^A-Za-z0-9]", "_");
|
||||
}
|
||||
|
||||
private static String beanString(ObjectName beanName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(beanName.getDomain());
|
||||
|
||||
Hashtable<String, String> properties = beanName.getKeyPropertyList();
|
||||
|
||||
String keyspace = "keyspace";
|
||||
if (properties.containsKey(keyspace)) {
|
||||
sb.append('.');
|
||||
sb.append(properties.get(keyspace));
|
||||
properties.remove(keyspace);
|
||||
}
|
||||
|
||||
String type = "type";
|
||||
if (properties.containsKey(type)) {
|
||||
sb.append('.');
|
||||
sb.append(properties.get(type));
|
||||
properties.remove(type);
|
||||
}
|
||||
|
||||
ArrayList<String> keys = new ArrayList(properties.keySet());
|
||||
Collections.sort(keys);
|
||||
|
||||
for(String key : keys) {
|
||||
sb.append('.');
|
||||
sb.append(properties.get(key));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
// return beanName.getCanonicalName();
|
||||
}
|
||||
|
||||
public void output(ObjectName beanName, String attributeName, Object value) {
|
||||
Value.flatten(beanName, attributeName, value, new Value.Listener() {
|
||||
public void value(ObjectName beanName, String attributeName, String value) {
|
||||
final Number v = enums.resolve(Enums.id(beanName, attributeName), value);
|
||||
if (v != null) {
|
||||
value(beanName, attributeName, v);
|
||||
} else {
|
||||
value(beanName, attributeName, Double.NaN);
|
||||
}
|
||||
}
|
||||
public void value(ObjectName beanName, String attributeName, Number value) {
|
||||
final String v;
|
||||
|
||||
if (Double.isNaN(value.doubleValue())) {
|
||||
v = "U";
|
||||
} else {
|
||||
final NumberFormat f = NumberFormat.getInstance();
|
||||
f.setMaximumFractionDigits(2);
|
||||
f.setGroupingUsed(false);
|
||||
v = f.format(value);
|
||||
}
|
||||
|
||||
System.out.println(attributeName(beanName, attributeName) + ".value " + v);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user