Subscribe to Spring Metrics channel

2019-06-01 16:03发布

So according to the documents of Spring it will publish metrics on a REST endpoint and a message channel.

The REST endpoint works fine as I get the expected result. However I would like to handle each change in the metrics. So it says it will by default publish messages to a channel called "metricsChannel"

I tried to create the following class which would listen to this channel, but it does not seem to fire. Everything else has been kept default for the Spring Boot application.

package services.core;

import org.springframework.stereotype.Service;
import org.springframework.integration.annotation.ServiceActivator;

@Service
public class MetricService {
    @ServiceActivator(inputChannel = "metricsChannel")
    public void handleMessage(org.springframework.messaging.Message<?> message) {
        System.out.println("Message [" + message.toString() + "] is received");
    }
}

2条回答
冷血范
2楼-- · 2019-06-01 16:13

To clarify: my code did actually work, but for me it felt like a gotcha.

Quote from Spring docs:

If the ‘Spring Messaging’ jar is on your classpath a MessageChannel called metricsChannel is automatically created (unless one already exists). All metric update events are additionally published as ‘messages’ on that channel. Additional analysis or actions can be taken by clients subscribing to that channel.

So by "all metric update events", I thought that the system metrics (memory usage, cpu load etc.) would fall under these events. Actually they are not, they are just being published whenever your custom counters change or for example the number of requests for a certain endpoint.

Initially I was waiting for a message each second or so after bootup, to no avail. Ultimately started to call the metrics endpoint and suddenly the messages starting popping in the console/channel each time I called it.

查看更多
ら.Afraid
3楼-- · 2019-06-01 16:28

I've just tested that and works well:

@Bean
@ServiceActivator(inputChannel = "metricsChannel")
public MessageHandler metricsHandler() {
    return System.out::println;
}

I've done that in our web-sockets sample on the server part. Added this:

compile 'org.springframework.boot:spring-boot-starter-actuator'

to that project Gradle config.

And I see this in console, when I started the client app:

GenericMessage [payload=Metric [name=gauge.response.time.star-star, value=26.0, timestamp=Tue Apr 14 16:03:53 EEST 2015], headers={metricName=gauge.response.time.star-star, id=08697a97-83c1-5000-f031-65f6797c0cd8, timestamp=1429016633672}]
GenericMessage [payload=Metric [name=counter.status.101.time.star-star, value=1, timestamp=Tue Apr 14 16:03:53 EEST 2015], headers={metricName=counter.status.101.time.star-star, id=8d070cb4-88e8-f5a7-6b83-6b27edf75bfc, timestamp=1429016633674}]

But, yes: your code is good as well.

查看更多
登录 后发表回答