Search code examples
springmetricsprometheusmicrometer

Prometheus + Micrometer: how to record time intervals and success/failure rates


I am sending from a front-end client to a metrics-microservice a JSON with the following data:

{
    totalTimeOnTheNetwork: number;
    timeElasticsearch: number;
    isSuccessful: boolean;
}

The metrics-microservice currently handles the data like this:

@AllArgsConstructor
@Service
public class ClientMetricsService {
    @Autowired
    MeterRegistry registry; // abstract class, SimpleMeterRegistry gets injected
    public void metrics(final MetricsProperty metrics) {
        final long networkTime = metrics.getTotalTime() - metrics.getElasticTime();
        registry.timer(ELASTIC_TIME_LABEL).record(metrics.getElasticTime(), TimeUnit.MILLISECONDS);
        registry.timer(TOTAL_TIME_LABEL).record(metrics.getTotalTime(), TimeUnit.MILLISECONDS);
        registry.timer(NETWORK_TIME_LABEL).record(networkTime, TimeUnit.MILLISECONDS);
    }
}

As you can see I make a new metric for each of the time intervals. I was wondering if I can put all the intervals into one metric? It would be great if I did not have to calculate network-time on the metrics-microservice but rather in Grafana.

Also, could I put a success/failure tag inside the registry.timer? I assume I need to use a timer.builder on every request then like this:

Timer timer = Timer
    .builder("my.timer")
    .description("a description of what this timer does") // optional
    .tags("region", "test") // optional
    .register(registry);

Is that a typical way to do it (eg create a new timer on every HTTP request and link it to the registry) or should the timer be derived from the MeterRegistry like in my current version?

Or would you use another metric for logging success/failure? In the future instead of a boolean, the metric might change to a http-error-code for example, so I am not sure how to implement it in a maintainable way


Solution

  • Timer timer = Timer
        .builder("your-timer-name-here")
        .tags("ResponseStatus", isSuccessful.toString, "ResponseCode", http-error-code.toString)
        .register(registry);
    
    timer.record(metrics.getTotalTime);
    

    Should be working code that responds to your question but I have a feeling there is a misunderstanding. Why do you want everything in one metric?

    Either way you can probably sort that out with tags. I do not know the capabilities on the Grafana end but it might be as simple as throwing the .getElasticTime info into another tag and sending it through.