2
votes

I have a web application (war) with Jersey REST endpoints. I am integrating with prometheus / micrometer for generating metrics. I have exposed "/metrics" endpoint as in here

@Path("/metrics")
public class Metrics {
    private static final PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);

    static {
        new JvmGcMetrics().bindTo(prometheusRegistry);
        new JvmMemoryMetrics().bindTo(prometheusRegistry);
        new JvmCompilationMetrics().bindTo(prometheusRegistry);
        new JvmThreadMetrics().bindTo(prometheusRegistry);
    }
    @GET
    public String getMetrics() {
        return prometheusRegistry.scrape();
    }
}

I am stuck on how to generate http request metrics. I could not find any code that would relevant to get these metrics. Can someone help me on this ?

2
Just to be clear, your JVM metrics are being published correctly to Prometheus. And you are looking to record HTTP Requests and expose those as metrics?checketts
Yes, that's right. There isn't a straightforward way to achieve. Just came across github.com/micrometer-metrics/micrometer/tree/master/…. Have you tried this ?DBS

2 Answers

5
votes

Alternatively to what checketts proposed, you could make use of the Jersey server instrumentation of Micrometer which is present even prior to the 1.0.0 release in the form of micrometer-jersey2 library. You can find the source here.

Your entrypoint to this is the MetricsApplicationEventListener which can be registered with Jerseys ResourceConfig. For an example, you can have a look at the test class on how this could be done.

You can also have a look at how this is integrated/autoconfigured in Spring Boot here.

One last note: Spring Boots metric name is http.server.requests (to distinguish them from HTTP client request metrics) and if you one day will move to Spring Boot or your platform is already running Spring Boot applications, your non Spring Boot HTTP requests metrics will nicely match without further ado.

1
votes

You'll need to include a Filter to record each request as it comes through. See https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java for how Spring does it.

I would recommend against using a static registry if possible and using dependency injection instead.

Here is a tiny example of what you might do within a filter's doFilter method

        long start = System.nanoTime()
        try {
            filterChain.doFilter(request, response);
            long durationNanos = System.nanoTime() - start;
            prometheusRegistry.timer("http.server.requests", "status", response.getStatus().toString()).record(durationNanos, TimeUnit.NANOSECONDS)
        } catch (Exception ex) {
            //Equivalent exception timer recording
            throw ex;
        }