Spring Boot automagically (with the actuator) provides metrics for queues (spring_rabbitmq_listener*
).
Is there a way to get similar metrics for the exchanges a services sends to?
The application is using
org.springframework.boot:spring-boot-starter-actuator
org.springframework.boot:spring-boot-starter-amqp
org.springframework.boot:spring-boot-starter-web
all in 3.1.0
I've tried rabbitTemplate.setObservationEnabled(true);
but that doesn't help.
Unlike the listener containers, the RabbitTemplate
(used to send messages to exchanges) does not support classic Micrometer Timers.
However, starting with version 3.0, you can enable Observation by Micrometer which does include Micrometer metrics (as well as adding tracing capabilities).
Note that if you enable observation for the listener containers, the default metrics are disabled (because it doesn't make sense to maintain both). The observation metrics have slightly different tags.
https://docs.spring.io/spring-amqp/docs/current/reference/html/#micrometer-observation
Using Micrometer for observation is now supported, since version 3.0, for the RabbitTemplate and listener containers.
Set
observationEnabled
on each component to enable observation; this will disable Micrometer Timers because the timers will now be managed with each observation. When using annotated listeners, setobservationEnabled
on the container factory.
EDIT
This works fine for me:
@SpringBootApplication
public class So76530102Application {
public static void main(String[] args) {
SpringApplication.run(So76530102Application.class, args).close();
}
@Bean
ApplicationRunner runner(RabbitTemplate template, MeterRegistry registry) {
template.setObservationEnabled(true);
return args -> {
template.convertAndSend("foo", "bar", "test");
Timer timer = registry.get("spring.rabbit.template")
.tagKeys("spring.rabbit.template.name", "error")
.timer();
System.out.println(timer.count());
};
}
}
1
However, the timer does not contain any information about the exchange or routing key (the trace data does have that information with the form exchange/rk
).
EDIT2
If you want to add the exhange/rk as a tag to the meter...
@SpringBootApplication
public class So76530102Application {
public static void main(String[] args) {
SpringApplication.run(So76530102Application.class, args).close();
}
@Bean
ApplicationRunner runner(RabbitTemplate template, MeterRegistry registry) {
template.setObservationEnabled(true);
template.setObservationConvention(new MyConvention());
return args -> {
template.convertAndSend("foo", "bar", "test");
registry.getMeters().stream()
.filter(m -> m.getId().getName().equals("spring.rabbit.template"))
.forEach(m -> System.out.println(m.getId()));
Timer timer = registry.get("spring.rabbit.template")
.tagKeys("spring.rabbit.template.name", "error")
.tag("dest", "foo/bar")
.timer();
System.out.println(timer.count());
};
}
}
class MyConvention extends DefaultRabbitTemplateObservationConvention {
@Override
public KeyValues getLowCardinalityKeyValues(RabbitMessageSenderContext context) {
return super.getLowCardinalityKeyValues(context).and("dest", context.getDestination());
}
}
MeterId{name='spring.rabbit.template', tags=[tag(dest=foo/bar),tag(error=none),tag(spring.rabbit.template.name=rabbitTemplate)]}
1