reactor / reactor-core

Non-Blocking Reactive Foundation for the JVM
http://projectreactor.io
Apache License 2.0
4.92k stars 1.19k forks source link

Document difference between Micrometer.metrics() and Micrometer.observation() #3423

Closed maciej-gromul closed 2 weeks ago

maciej-gromul commented 1 year ago

Documentation Issue

I believe it would be beneficial to write down the difference in usage tap operator with Micrometer.observation() in different stages of defined pipeline. For example below we get 1 sec difference just with simple flatmap. If we offload our tasks after first tap to another scheduler and concatmap instead of flatmap, we would get 10sec difference. It would be worth writing down that it actually awaits the completion of whole publisher defined just before that tap and it actually cares only about context of a flux publisher as whole in comparison to previous Flux.just(1,2,3).metrics() that would observe additionally time between onNext calls and define a metric for those. Now to achieve that we need to write manual observations for that.

var meterRegistry = new SimpleMeterRegistry();
var registry = ObservationRegistry.create();
registry.observationConfig()
  .observationHandler(new DefaultMeterObservationHandler(meterRegistry));

var source = Flux.range(1, 10);
source.name("test1")
  .tag("foo", "bar")
  .tap(Micrometer.observation(registry))
  .flatMap(i -> Mono.delay(Duration.ofSeconds(1)))
  .name("test2")
  .tap(Micrometer.observation(registry))
  .blockLast();

meterRegistry.getMeters()
  .stream()
  .filter(meter -> !meter.getId().getName().endsWith(".active"))
  .forEach(
    meter -> {
       System.out.println();
       meter.measure().forEach(measurement -> System.out.println(
         meter.getId().getName()
         + " | "
         + measurement.getStatistic().name()
         + ":" + measurement.getValue()
       )
    );
  }
);
test2 | COUNT:1.0
test2 | TOTAL_TIME:1.056872122
test2 | MAX:1.056872122

test1 | COUNT:1.0
test1 | TOTAL_TIME:0.048378594
test1 | MAX:0.048378594

Improvement Suggestion

Define simple examples showing the importance of placement of the tap subscriptions. It would be nice as well to document what is the output schema of the metrics that will be generated like it had been previously pointing to micrometer page for .metrics() operator.

chemicL commented 1 month ago

From the javadoc of Micrometer.observation():

The Observation covers the entire length of the sequence, from subscription to termination

In the reference documentation we also have the list of metrics created by Micrometer.metrics() and by Micrometer.observation(). The one for Observation doesn't list the onNextDelay notion. It might be worth documenting the difference in one form or another, so let's keep this one open despite not gaining much attention for over a year. Perhaps someone is eager to contribute. @maciej-gromul seems you already had some ideas, are you willing to enhance the reference docs with regards to what you suggest?

chemicL commented 2 weeks ago

I think it's resolved with #3862