Siegfried Goeschl bio photo

Siegfried Goeschl

Email Github

The goal of JavaMelody is to monitor Java or Java EE application servers in QA and production environments.

JavaMelody Sample Graph

The really nice thing is sthe storage of historical data - you can have a look at the same graphs spanning a week, a month or a year without setting up any additional infrastructure. Therefore JavaMelody is installed on every production system I work on.

Securing JavaMelody Installation

If you want BASIC authentication with username and password, but do no want to use a realm and “security-constraint” in web.xml, you can add the parameter “authorized-users” in web.xml, in context or in system properties like the other javamelody parameters (since v1.53). For example in your WEB-INF/web.xml file:

<filter>
        <filter-name>monitoring</filter-name>
        <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
        <init-param>
                <param-name>authorized-users</param-name>
                <param-value>user1:pwd1, user2:pwd2</param-value>
        </init-param>
</filter>

Security Manager

If you are running into an active security manager the following snippets helps

grant codeBase "file:${catalina.home}/webapps/<your_webapp>/WEB-INF/lib/javamelody-x.jar" {
        permission java.security.AllPermission;
};
grant codeBase "file:${catalina.home}/webapps/<your_webapp>/WEB-INF/lib/jrobin-1.5.9.1.jar" {
        permission java.security.AllPermission;
};    Ï

Disabling JavaMelody

You can disable JavaMelody using

  • disabled=false using the init parameter in web.xml
  • pass -Djavamelody.disabled=true as system property

Avoiding Unique Identifier URLs

JavaMelody created unique RRD files for each URL and SQL request so if you have thousands of unique URLs we need a lot of file handles and disk storage

The proposed solution is to use the http-transform-pattern and sql-transform-pattern parameters. These options work is by replacing any part of the URL that matches the regular expression with a “$”.

So setting http-transform-pattern to \d+ means that the URLs http://server/get/entity/10 and http://server/get/entity/20 both have their digits matched by the regular expression, and are then aggregated into the URL http://server/get/entity/$. This in turn reduces the number of RRD files, as new ones are no longer created for every id.

For more information check http://stackoverflow.com/questions/19147762/javamelody-crashing-the-server-with-thousands-of-rrd-files.

A More Complete Example

A small example working for Wildfly “Hello World”

  • Use javamelody-core-1.54.0
  • Use “javamelody:jm123” for HTTP Basic Authentication
  • Use “/admin/javamelody” instead of “/monitoring” to have a common “admin” infix for all URLs
  • Store JavaMelody’s historical data under “/Users/sgoeschl/temp/javamelody/wildfly-helloworld_klendathu.local” in my case
  • Open [http://localhost:8080/wildfly-helloworld/admin/javamelody http://localhost:8080/wildfly-helloworld/admin/javamelody]

Maven Integration

<!-- Minimal dependencies for JavaMelody -->
<dependency>
    <groupId>net.bull.javamelody</groupId>
    <artifactId>javamelody-core</artifactId>
    <version>1.54.0</version>
</dependency>
<dependency>
    <groupId>org.jrobin</groupId>
    <artifactId>jrobin</artifactId>
    <version>1.5.9</version>
</dependency>

Web Application Integration

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <display-name>WildFly Quickstart</display-name>

    <filter>
        <filter-name>monitoring</filter-name>
        <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
        <init-param>
            <!-- restrict access using HTTP basic authentication -->
            <param-name>authorized-users</param-name>
            <param-value>javamelody:javamelody</param-value>
        </init-param>
        <init-param>
            <!-- set a different URL for monitoring -->
            <param-name>monitoring-path</param-name>
            <param-value>/admin/javamelody</param-value>
        </init-param>
        <init-param>
            <!-- enable/disable JavaMelody -->
            <param-name>disabled</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <!-- define an storage path for JavaMelodys historical data -->
            <param-name>storage-directory</param-name>
            <param-value>/Users/sgoeschl/temp/javamelody</param-value>
        </init-param>        
    </filter>
    <filter-mapping>
        <filter-name>monitoring</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>net.bull.javamelody.SessionListener</listener-class>
    </listener>
    
</web-app>