2

I have set up micronaut using the cli and want to add an endpoint that provides prometheus metrics. Following the guides (and Micronaut: How to get metrics in the Prometheus format?), I added things to my application.yml the following way:

micronaut:
  application:
    name: foo-service
  metrics:
    enabled: true
    export:
      prometheus:
        enabled: true
        step: PT1M
        descriptions: true
endpoints:
  metrics:
    enabled: true
  prometheus:
    enabled: true
    sensitive: false

Now I have two endpoints, one at /metrics and one at /prometheus. However, I want /metrics to return prometheus metrics. Any idea how I can achieve that?

I know I could go and put all endpoints under a sub-path, such as /endpoints using endpoints.all.path and then proxy to there, but that really is ugly and not that way I want to solve it.

lena_punkt
  • 369
  • 2
  • 10

3 Answers3

2

The example given by lena_punkt works for me. I will just add a Java example and some confs which were necessary for me in my application.yml.

endpoints:
  metrics:
    enabled: false
    sensitive: false
  prometheus:
    enabled: false
    sensitive: false
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;

import javax.inject.Inject;

@RequiresMetrics
@Controller("/metrics")
public class PrometheusController {

    private final PrometheusMeterRegistry prometheusMeterRegistry;

    @Inject
    public PrometheusController(PrometheusMeterRegistry prometheusMeterRegistry) {
        this.prometheusMeterRegistry = prometheusMeterRegistry;
    }

    @Get
    @Produces("text/plain")
    public String metrics() {
        return prometheusMeterRegistry.scrape();
    }
}
Arnaud Villevieille
  • 1,039
  • 2
  • 10
  • 24
1

You can disable the metrics endpoint and create a controller that responds to /metrics. That controller could inject the PrometheusEndpoint and delegate the call the to the endpoint bean.

James Kleeh
  • 12,094
  • 5
  • 34
  • 61
  • That only works partially. I can add a controller that binds to `/metrics` and inject the `PrometheusEndpoint`. But that one is only available as a bean when it is enabled in `application.yml`, which makes it available at `/prometheus`. So now I have it available on two paths. Any chance to not have it bind to `/prometheus`? – lena_punkt May 24 '19 at 04:04
1

Thanks to james-kleeth I got to the right track, although it basically is a re-implementation. I disabled the prometheus endpoint and added a controller. However, when the endpoint is disabled I cannot inject it anymore. Its implementation was "trivial" (just referencing to the prometheus registry). This is my solution:

package my.company.service

import io.micrometer.prometheus.PrometheusMeterRegistry
import io.micronaut.configuration.metrics.annotation.RequiresMetrics
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import io.swagger.v3.oas.annotations.Operation
import javax.inject.Inject

@RequiresMetrics
@Controller("/metrics")
class MetricsController @Inject constructor(val prometheusMeterRegistry: PrometheusMeterRegistry) {
    @Operation(summary = "Provide metrics in Prometheus format")
    @Get
    @Produces("text/plain; version=0.0.4")
    fun metrics(): String = prometheusMeterRegistry.scrape()
}
lena_punkt
  • 369
  • 2
  • 10