1. Metrics

Metrics provides a powerful toolkit of ways to measure the behavior of critical components in your production environment.

1.1. Usage

1) Add the dependency:

Maven
Gradle
<!-- Metrics Module-->
<dependency>
  <groupId>io.jooby</groupId>
  <artifactId>jooby-metrics</artifactId>
  <version>3.5.3</version>
</dependency>

2) Install and configure the module

Java
Kotlin
{
  install(new MetricsModule()
      .threadDump()
      .ping()
      .healthCheck("deadlock", new ThreadDeadlockHealthCheck())
      .metric("memory", new MemoryUsageGaugeSet())
      .metric("threads", new ThreadStatesGaugeSet())
      .metric("gc", new GarbageCollectorMetricSet())
      .metric("fs", new FileDescriptorRatioGauge()));
}

Let’s see what all these means.

1.2. Metrics

Metrics are available at /sys/metrics or /sys/metrics/:type via:

Java
Kotlin
{
  install(new MetricsModule()
      .metric("memory", new MemoryUsageGaugeSet())
      .metric("threads", new ThreadStatesGaugeSet())
      .metric("gc", new GarbageCollectorMetricSet())
      .metric("fs", new FileDescriptorRatioGauge()));
}

The /:type parameter is optional and let you filter metrics by type counters, gauges, etc.

There is a name filter too: /sys/metrics?name=memory or /sys/metrics/guages?name=memory. The name parameter filter all the metrics where the name starts with the given name.

1.3. Health Checks

Health checks are available at /sys/healthCheck via:

Java
Kotlin
{
  install(new MetricsModule()
      .healthCheck("deadlock", new ThreadDeadlockHealthCheck());
}

1.4. Instrumented Requests

Use the MetricsDecorator decorator to capture request information (like active requests or min/mean/max execution time) and a breakdown of the response codes being returned for a selection of routes:

Java
Kotlin
{
  use(new MetricsModule());

  // inspected route
  get("/", context -> "Hello metrics!");
}

1.5. Thread Dump

A thread dump is available at /sys/threadDump via:

Java
Kotlin
{
  install(new MetricsModule()
      .threadDump();
}

1.6. Reporting

Reporters are appended via a callback API:

Java
Kotlin
{
  install(new MetricsModule()
      .reporter(registry -> {
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
            .convertDurationsTo(TimeUnit.SECONDS)
            .convertRatesTo(TimeUnit.SECONDS)
            .build();
        reporter.start(1, TimeUnit.HOURS);
        return reporter;
      });
}

You can add all the reporters you want. Keep in mind you have to start them (if need it), but you don’t have to stop them as long they implement the java.io.Closeable interface.

1.7. Using with jooby-hikari

You can instrument the database pool by passing MetricRegistry and HealthCheckRegistry instances to the configuration methods of HikariModule, but you must use the same instances with MetricsModule:

Java
Kotlin
{
  MetricRegistry metricRegistry = new MetricRegistry();
  HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();

  install(new HikariModule()
      .metricRegistry(metricRegistry)
      .healthCheckRegistry(healthCheckRegistry));

  install(new MetricsModule(metricRegistry, healthCheckRegistry));
}

1.8. Alternate Routes

Use constructor overloads of MetricsModule to change the default /sys prefix of the routes registered by the module:

Java
Kotlin
{
  install(new MetricsModule("/diag")
      .threadDump();
}