Getting started

1. Maven dependencies

Add the following dependency.

    <dependency>
      <groupId>org.avaje.metric</groupId>
      <artifactId>avaje-metric-core</artifactId>
      <version>4.4.2</version>
    </dependency>

2. Maven plugin enhancement

Add the maven plugin below specifying the packages that should be scanned for classes annotated with @Singleton, @Path, @Service etc.

You can also use the Avaje Metrics @Timed annotation.

    <build>
      <plugins>

        <plugin>
          <groupId>org.avaje.metric</groupId>
          <artifactId>enhance-maven-plugin</artifactId>
          <version>4.2.1</version>
          <executions>
            <execution>
              <id>main</id>
              <phase>process-classes</phase>
              <configuration>
                <classSource>target/classes</classSource>
                <packages>org.example.myapp.**</packages>
                <transformArgs>debug=1</transformArgs>
              </configuration>
              <goals>
                <goal>enhance</goal>
              </goals>
            </execution>
          </executions>
        </plugin>

      </plugins>
    </build>

    

3. Reporting

Add MetricReporter to your application. This has a Timer that will fire periodically and collect the metrics and send then to a reporter.

    import org.avaje.metric.report.MetricReportConfig;
    import org.avaje.metric.report.MetricReportManager;
    ...

    // There are default reporters that come with avaje-metric-core.
    // Defaults to writing metrics in a csv format every 60 seconds.
    // A daily file is written keeping a maximum of 20 file

    MetricReportConfig config = new MetricReportConfig();

    // report aggregate statistics every 10 seconds
    config.setFreqInSeconds(10);

    MetricReportManager reportManager = new MetricReportManager(config);

... and you're off

At this point you can run your application and metrics will be written to a csv file every minute.

Output example:

00:00:51, lg, jvm.gc.ps-marksweep, count=4, time=1556
00:00:51, lg, jvm.gc.ps-scavenge, count=48, time=6811
00:00:51, dg, jvm.memory.heap, pct=23.0, init=61.75, used=210.21, committed=379.5, max=878.5
00:00:51, dg, jvm.memory.nonheap, pct=4.0, init=23.44, used=9.12, committed=23.44, max=214.0
00:00:51, dm, jvm.os.loadAverage, value=1.17
00:00:51, dm, jvm.system.uptime, value=0.0
00:00:51, lg, jvm.threads, current=5, peak=5, daemon=4
00:00:51, tm, org.example.MyService.performLogin, count=34, avg=28972, max=39150, sum=985073, dur=60, err.count=0
00:00:51, tm, org.example.MyService.checkWeather, count=1, avg=954, max=954, sum=954, dur=60, err.count=0
  
Notes:
  • Times are reported in microseconds. avg=28972 means an average of 29 milliseconds.
  • If a metric had no events since the last collection it is considered 'empty' and not reported and you won't see it in the output
  • dur=60 means that the duration that the metric covers is 60 seconds. This is effectively the number of seconds since the last collection (which is when the counters where last reset).
  • Some core JVM gauges for GC, Memory, Threads etc are automatically registered.

4. Refine metric names

The metric names are the full package class and method names. This is ok but you might want to modify those names because they are long and you want to use some common prefixes like web.api, service, db, integration instead. Using the common prefixes can make it easier to rollup/group related metrics together.

Add a file called metric-name-mapping.txt into src/main/resources and add some name=value pairs which will be used to truncate/replace part or all of the package name.

org.example.myapp.endpoint=web.api
org.example.myapp.repository.dao=dataaccess
org.example.myapp=myapp