Currently we access stats via logs which WebSocketMessageBrokerStats produce. Would you consider exporting those metrics to any stats collector? If interested, we can create a pr for this.

https://stackoverflow.com/questions/57481608/how-to-access-and-export-websocketmessagebrokerstats-internal-counts

Comment From: bclozel

Sorry for the delayed response.

Spring Framework only depends on the Observation API and this use case doesn't fit as Observation is all about timer metrics and traces. Here, we could expose stats information and let developers bind Gauges to their MeterRegistry using the "micrometer-core" dependency.

The log line contains several parts:

WebSocketSession[...], stompSubProtocol[...], stompBrokerRelay[...], inboundChannel[...], outboundChannel[...], sockJsScheduler[...]

The "inboundChannel", "outboundChannel" and "sockJsScheduler" are all Stringly typed as this information is extracted directly from ThreadPoolExecutor#toString. I don't think we can expose more detailed stats. At best, we could expose the Executor directly and let developers extract information from there.

As for the "WebSocketSession", "stompSubProtocol", "stompBrokerRelay", they all have dedicated Stats interface that are already public. We could add methods like the following to WebSocketMessageBrokerStats and deprecate the String versions to avoid redundancy:

@Nullable
public StompSubProtocolHandler.Stats getStompSubProtocolStats() {
    return (this.stompSubProtocolHandler != null ? this.stompSubProtocolHandler.getStats() : null);
}

This would allow applications to register gauges with the metric names and tags of their choices:

MeterRegistry meterRegistry = ...;

Gauge.builder("spring.stomp.frames", stats.getStompSubProtocolStats(), StompSubProtocolHandler.Stats::getTotalConnect)
            .tag("type", "CONNECT")
            .description("number of CONNECT frames processed")
            .register(meterRegistry);

Gauge.builder("spring.stomp.frames", stats.getStompSubProtocolStats(), StompSubProtocolHandler.Stats::getTotalConnected)
            .tag("type", "CONNECTED")
            .description("number of CONNECTED frames processed")
            .register(meterRegistry);

The only downside here is that such metrics would probably fit more with Counter, but counters need to be incremented manually by the instrumentation rather than polling like Gauges do.

@nyilmaz What do you think about this proposal?

Comment From: nyilmaz

This would be perfectly OK and enough form most of the time, also leaving metering library free to choose. Thanks for your attention 👍 and observation! A separate bean can be defined to automatically wired in to collect those metrics and expose them via prometheus, however my last sentence addresses spring-boot's side I think.

How can we proceed from now on?

Comment From: bclozel

I'll take care of it. Thanks for your feedback!