0

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.

Martin Schröder
  • 4,176
  • 7
  • 47
  • 81

1 Answers1

1

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, set observationEnabled 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
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Hrrm. As I wrote in my question, I already have `rabbitTemplate.setObservationEnabled(true);`. I get some metrics like `rabbitmq_published_total{name="connectionFactory",} `, though - probably from the rabbitmq driver, – Martin Schröder Jun 22 '23 at 14:49
  • 1
    Yes, those are from the `amqp-client`. It works fine for me; see the edit. – Gary Russell Jun 22 '23 at 16:18
  • 1
    I added another example showing how to add the exchange and routing key to the timers. – Gary Russell Jun 22 '23 at 16:36