REST JMX Monitoring
Published on 02/05/2011
3 min read
In category
jee
Ich bin wieder auf der JAX und auch bei Adam Bien. Beides ist nur zu empfehlen! ;-) Während des Workshops kamen wir auf REST und JMX und das es eigentlich eine gute Idee wäre, JMX Monitoring mittels REST anzubieten. Klingt interessant. Sofort ausprobiert.
Mit Eclipse mal fix ein dynamisches Webprojekt erstellt. Drauf geachtet, dass REST (JAX-RS) ausgewählt wird. Glassfish ist schon vom letzten Projekt in Eclipse integriert. Während der Projekterstellung bietet der Wizard u.a. die Konfiguration für REST an. Da kann u.a. das URL matching pattern eingeben werden (default: /rest/*)
Als erstes erstellen wir eine REST-Klasse die alle MBeans auflisten.
import java.lang.management.ManagementFactory;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
/\*\*
\* REST JMX Monitor
\*
\* @author haf
\*
\*/
@Path("rjm")
public class RestJmxMonitor {
@GET
@Path("all")
public String getAllMBeans() {
MBeanServer mbServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectInstance> mbeans = mbServer.queryMBeans(null, null);
StringBuilder sb = new StringBuilder();
sb.append("MBeans:<br />");
for(ObjectInstance oi: mbeans) {
sb.append(oi.getObjectName());
// sb.append(" - ");
// sb.append(oi.getClassName());
sb.append("<br />");
}
return sb.toString();
}
}
Glassfish starten. URL http://localhost:8080/JmxMonitor/rest/rjm/all
aufrufen und die ObjectNames der MBeans begutachten. Vielleicht noch ein paar Worte zu den ObjectNames. Diese identifizieren ein MBean eindeutig und hat folgendes Format: Domain-name:key1=value1[,key2=value2,...keyX=valueX] Weitere Details unter ObjectName.
Um z.B. die Attribute für ein bestimmten MBean anzuzeigen, kann man folgende Methode anbieten:
@GET
@Path("mb/{objectName : .+}")
public String getMBean(@PathParam("objectName") String objectName) {
MBeanServer mbServer = ManagementFactory.getPlatformMBeanServer();
StringBuilder sb = new StringBuilder();
try {
Set<ObjectInstance> mbeans = mbServer.queryMBeans(new ObjectName(objectName), null);
sb.append("MBeans:<br />");
for(ObjectInstance oi: mbeans) {
sb.append(oi.getObjectName());
sb.append("<br />");
final MBeanAttributeInfo\[\] attributes = mbServer.getMBeanInfo(oi.getObjectName()).getAttributes();
sb.append("Attributes:<br />");
for (final MBeanAttributeInfo attribute : attributes) {
sb.append("- ");
sb.append(attribute.getType());
sb.append(" ");
sb.append(attribute.getName());
sb.append("=");
Object value;
try {
value = mbServer.getAttribute(oi.getObjectName(), attribute.getName());
sb.append(value);
} catch (AttributeNotFoundException e) {
e.printStackTrace();
}
sb.append("<br />");
}
sb.append("<br />");
}
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (InstanceNotFoundException e) {
e.printStackTrace();
} catch (ReflectionException e) {
e.printStackTrace();
} catch (MBeanException e) {
e.printStackTrace();
}
return sb.toString();
}
Teste man dies z.B. mit http://localhost:8080/JmxMonitor/rest/rjm/mb/com.sun.appserv:type=Loader,path=/,host=server
erhält man die Attribute.
Hier sei angemerkt, dass der PathParam mit einem Regex angegeben wird, da der ObjectName das ungültige Zeichen / beinhalten kann. Falls man kein Regex verwenden möchte, kann ein @QueryParam verwendet werden.
Wie man sehen kann, kann man recht fix eine rudimentäre Implementierung eines JMX Monitor mit REST realisieren. Das ganze ist natürlich ausbaubar: bessere Suche (Domain, Query), andere Ausgabeformate, setzen von Werten etc.
Nächster Teil folgt.
Links: