Jolokia: JMX-Auswertung mit Cubism

Jolokia ist eine Jmx - Http Bridge, mit der man über den Browser MBeans einer Anwendung auslesen kann. Seit Jolokia 1.0.5 besteht die Möglichkeit, die ausgelesenen Werte mit der Javascript-Bibliothek Cubism aufzubereiten und grafisch darzustellen.
Beim Ausprobieren hatte ich diverse Problem, das Ganze zum Laufen zu bekommen. Daher habe ich mich entschieden, mein lauffähiges Projekt hier zu veröffentlichsen.

Zuerst habe ich ein Maven Projekt aufgesetzt und das Plugin com.devspan.mojo.javascript:javascript-maven-plugin:0.9.3 über das Sonatype Repository eingebunden.

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.ronnyfriedland.poc</groupId>
  <artifactId>jolokia-ui</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
      <dependency>
          <groupId>org.jolokia</groupId>
          <artifactId>jolokia-client-javascript</artifactId>
          <version>1.1.0</version>
          <type>javascript</type>
          <scope>compile</scope>
      </dependency>
  </dependencies>
  <build>
      <plugins>
          <plugin>
              <groupId>com.devspan.mojo.javascript</groupId>
              <artifactId>javascript-maven-plugin</artifactId>
              <version>0.9.3</version>
              <extensions>true</extensions>
              <configuration>
                  <useArtifactId>false</useArtifactId>
              </configuration>
              <executions>
                  <execution>
                      <goals>
                          <goal>war-package</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      </plugins>
  </build>
  <pluginRepositories>
      <pluginRepository>
          <id>sonatype-oss</id>
          <url>https://oss.sonatype.org/content/groups/public</url>
      </pluginRepository>
  </pluginRepositories>
</project>

Durch dieses Plugin werden 4 Javascript-Bibliotheken bereitgestellt, welche beim Bauen im target Verzeichnis landen:

  • scripts/lib/json2.js
  • scripts/lib/jolokia.js
  • scripts/lib/jolokia-simple.js
  • scripts/lib/jolokia-cubism.js

Zusätzlich werden aber noch Weitere benötigt, welche in das Projekt unter src/main/webapp/scripts/lib kopiert werden müssen.

  • scripts/lib/jquery.js
  • scripts/lib/d3.js
  • scripts/lib/cubism.v1.min.js
Nun kommen wir zum eigentlichen Thema - dem Auslesen und Auswerten der Daten. Ich habe einen Glassfish Server, auf dem Jolokia als WAR deployed ist. Die Url lautet in meinem Beispiel http://192.168.56.101:8080/jolokia. Ich möchte nun die prozentuale Auslastung des Heap-Speichers auslesen. Dafür soll der Wert jede Sekunde ausgelesen werden.
Weiterhin wird der darzustellende Werte ermittelt, berechnet (den Durchschnittswert) und der Variable memory gespeichert.

Die gesamte Konfiguration erfolgt direkt im Javascript.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- local -->
<script src="scripts/lib/jquery-1.7.2-min.js"></script>
<script src="scripts/lib/d3.js"></script>
<script src="scripts/lib/cubism.v1.min.js"></script>
<!-- provided -->
<script src="scripts/lib/json2.js"></script>
<script src="scripts/lib/jolokia.js"></script>
<script src="scripts/lib/jolokia-simple.js"></script>
<script src="scripts/lib/jolokia-cubism.js"></script>
<script type="text/javascript">
    // define jolokia source
    var j4p = new Jolokia({
        url : "http://192.168.56.101:8080/jolokia",
        fetchInterval : 1000
    });

    // create context
    var context = cubism.context().serverDelay(0).clientDelay(0).step(1000)
            .size(650);
    var jolokia = context.jolokia(j4p);

    // read heap memory in %
    var memory = jolokia.metric(function(resp1, resp2) {
        return Number(resp1.value) / Number(resp2.value);
    }, {
        type : "read",
        mbean : "java.lang:type=Memory",
        attribute : "HeapMemoryUsage",
        path : "used"
    }, {
        type : "read",
        mbean : "java.lang:type=Memory",
        attribute : "HeapMemoryUsage",
        path : "max"
    }, " ");

    // define colors
    var colors = [ "#FFF68F", "#8B864E" ];

    // Create graphs
    $(function() {
        d3.select("#memory").call(
                function(div) {

                    div.append("div").attr("class", "axis").call(
                            context.axis().orient("top"));

                    div.selectAll(".section").data([ memory ]).enter().append(
                            "div").call(
                            context.horizon().colors(colors).format(
                                    d3.format(".4p")));
                });

    });
</script>
</head>
<body>
  <div class="section">
    <h3>HeapMemory</h3>
    <div id="memory"></div>
  </div>
</body>
</html>

Für die Einbettung in die Html Seite muss noch ein Div-Tag mit der Id "memory" angegeben werden (welche im Javascript auch referenziert wird).

Am Ende kann das neue Artefakt, welches die Jolokia Daten aufbereitet, ebenfalls als WAR deployed werden.

Das vollständige Beispielprojekt befindet sich hier als Download.