Not a bug but proposal This ID is much more unique than WebSocketSession's own, is already part of public APIs available to Netty handlers and could be used, for example, to correlate log events happening at different levels in a Webflux app without resorting to reflective access
Comment From: rstoyanchev
A logPrefix
is exposed through session.getHandshakeInfo().getLogPrefix()
. On the server side this comes from ServerWebExchange#getLogPrefix()
and is based on the channel id. On the client side this doesn't seem to be used but we can improve on that and pass a similar prefix based on the channel id.
Comment From: bruto1
logPrefix is based on ChannelId.shortText, which is nowhere nearly unique enough for logging purposes - longText is much more useful
It would've been convenient to be able to compute the same unique or effectively unique value pertaining to a connection from both ChannelHandlerContext and ReactorNettyWebSocketSession
Comment From: rstoyanchev
The log prefix is unique, see #22039. It is also better to use a consistent log prefix.
If you really want to change this, you can access the channel id via ServerHttpRequest#getNativeRequest()
from a WebFilter
and insert it in the Reactor Context
.
Comment From: bruto1
log prefix is, but it's not available from ChannelHandlerContext the idea is to be able to generate logging events from both Netty handler level and Spring app level with some unique value which would allow to correlate them
ChannelId in general and its longValue in particular fits the bill, except there's no public API to retrieve it using WebSocketSession
As for your suggestion, request is accessible via ServerWebExchange in ReactorNettyRequestUpgradeStrategy.upgrade I could get away with adding ChannelId to subscriber context just there without adding a new WebFilter Would that be ok?
Comment From: bruto1
Thanks for the tip!
A bit more casting than I'd like:
(exchange, chain) ->
chain.filter(exchange)
.contextWrite(ctx -> ctx.put(ChannelId.class.getName(),
((AbstractServerHttpRequest) exchange.getRequest())
.<ChannelOperations>getNativeRequest()
.channel()
.id()))
but I guess it is public API and probably more conventional than getting channel and id from WebSocketSession itself via reflection
Comment From: rstoyanchev
I thought getNativeRequest
was exposed at the contract level. My bad, nevertheless getting on the level of the native request in this use case makes sense. We cannot make a channelId
available for all servers since they don't all expose that.
Comment From: bruto1
not all, just in ReactorNettyWebsocketSession would be enough since it imples a particular server
Comment From: rstoyanchev
You would still have to downcast, but fine we can expose this for the Reactor Netty session.
Comment From: bruto1
Thank you, @rstoyanchev