1

I have tried to follow the instructions to get drop wizard AspectJ metrics working, see https://github.com/astefanutti/metrics-aspectj however when I follow these simple instructions and view the metrics through JConsole mbeans there are no metrics reported for my annotated service, just metrics for the resource as is the default drop wizard behaviour.

I am using an old version of drop wizard so that there are no jar dependancy clashes with com.codahale.metrics artefacts

When the application is built hitting the following url produces a random string http://localhost:8080/string

Here is my simple example code:

pom.xml

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>test-project</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>

<name>test project</name>
<description>try and get aspect j metrics working in dropwizard following instructions on https://github.com/astefanutti/metrics-aspectj</description>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>0.7.1</version>
    </dependency>
    <dependency>
        <groupId>io.astefanutti.metrics.aspectj</groupId>
        <artifactId>metrics-aspectj</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.codahale.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>3.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.codahale.metrics</groupId>
        <artifactId>metrics-annotation</artifactId>
        <version>3.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.7</version>
    </dependency>
    <!-- 
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
     -->
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>io.astefanutti.metrics.aspectj</groupId>
                        <artifactId>metrics-aspectj</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <createDependencyReducedPom>true</createDependencyReducedPom>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <manifestEntries>
                                    <Premain-Class>org.aspectj.weaver.loadtime.Agent</Premain-Class>
                                    <Main-Class>com.example.MyApplication</Main-Class>
                                </manifestEntries>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

MyApplication.java

package com.example;

import com.example.service.MyService;
import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

public class MyApplication extends Application<MyConfiguration> {

public static void main(String[] args) throws Exception {
    MyApplication app = new MyApplication();
    app.run(args);
}

@Override
public void initialize(Bootstrap<MyConfiguration> arg0) {

}

@Override
public void run(MyConfiguration configuration, Environment environment) throws Exception {
    environment.jersey().register(new MyResource(new MyService()));
}

}

MyConfiguration.java

package com.example;

import io.dropwizard.Configuration;

public class MyConfiguration extends Configuration {
}

MyResource.java

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.codahale.metrics.annotation.Timed;
import com.example.service.MyService;

@Path("/string")
@Produces(MediaType.APPLICATION_JSON)
public class MyResource {

private final MyService service;

public MyResource(MyService service) {
    this.service = service;
}

@GET
@Timed
public String getString() {
    return "string is [" + this.service.constructString() + "]";
}

}

MyService.java

package com.example.service;

import java.util.Random;
import com.codahale.metrics.annotation.Timed;
import io.astefanutti.metrics.aspectj.Metrics;

@Metrics(registry = "myRegistry")
public class MyService {

private final Random random = new Random();

@Timed(name = "myTimedMethod")
public String constructString() {
    byte[] bytes = new byte[20];
    this.random.nextBytes(bytes);
    return new String(bytes);
}

}

example.yml

logging:
  level: INFO

I build the shaded jar on the command line with standard maven command:

mvn clean install

And run the jar with the following command:

java -jar -javaagent:<path-to-maven-repo>/org/aspectj/aspectjweaver/1.8.7/aspectjweaver-1.8.7.jar target/test-project-0.0.1-SNAPSHOT.jar server example.yml 

I am not quite sure what I am missing but a day spent searching didn't yield any useful insights.

pootle5
  • 21
  • 3

1 Answers1

1

So it turns out that what you have to do is register your MetricRegistry with a JmxReporter for the metrics to come out on JMX.

It seems that in the latest version of drop wizard you should be able to create a MetricRegistry and add this to the bootstrap metrics in the initialize method of your application

@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
    MetricRegistry myRegistry = SharedMetricRegistries.getOrCreate("myRegistry");
    MetricRegistry bootstrapMetricRegistry = bootstrap.getMetricRegistry();
    bootstrapMetricRegistry.register("myRegistry", myRegistry);
}

and then when this gets automatically put in a JMX reporter in the registerMetrics method of the bootstrap, however this doesn't seem to work.

My current solution is as follows, in the run method of the application grab the registry from the shared registry and build another JmxReporter. Metrics happily now appear when connecting through JMX.

@Override
public void run(MyConfiguration configuration, Environment environment) throws Exception {
    ...
    JmxReporter.forRegistry(SharedMetricRegistries.getOrCreate("myRegistry")).build().start();
    ...
}
pootle5
  • 21
  • 3