Nothing measures how many bytes an interaction puts on the wire. This is the cheapest answer to "is it the network or the server", and it is the number that explains a ComboBox with a ComponentRenderer and a 50-item page feeling slow: the server may report 40 ms while several hundred kilobytes cross the wire per keystroke.
Why this is easy
The kit already owns the filter chain that sees the UIDL body. ResyncDetectionFilter and SpringResyncDetectionFilter buffer the request through CachedBodyHttpServletRequest so ResyncInspector can classify it. A counting HttpServletResponseWrapper beside that gives the response side.
No Flow change is required.
Proposed work
Record two distribution summaries, only for UIDL requests:
vaadin.uidl.request.bytes
vaadin.uidl.response.bytes
Tagged by route through RouteTagResolver, so cardinality stays inside the existing routeCardinalityLimit, and by the interaction kind the request interceptor already resolves (poll / navigation / rpc), which separates a heartbeat from a real data load.
Gate it behind a setting in ObservabilitySettings / ObservabilityProperties, consistent with resync and database.
Nothing measures how many bytes an interaction puts on the wire. This is the cheapest answer to "is it the network or the server", and it is the number that explains a
ComboBoxwith aComponentRendererand a 50-item page feeling slow: the server may report 40 ms while several hundred kilobytes cross the wire per keystroke.Why this is easy
The kit already owns the filter chain that sees the UIDL body.
ResyncDetectionFilterandSpringResyncDetectionFilterbuffer the request throughCachedBodyHttpServletRequestsoResyncInspectorcan classify it. A countingHttpServletResponseWrapperbeside that gives the response side.No Flow change is required.
Proposed work
Record two distribution summaries, only for UIDL requests:
vaadin.uidl.request.bytesvaadin.uidl.response.bytesTagged by route through
RouteTagResolver, so cardinality stays inside the existingrouteCardinalityLimit, and by the interaction kind the request interceptor already resolves (poll/navigation/rpc), which separates a heartbeat from a real data load.Gate it behind a setting in
ObservabilitySettings/ObservabilityProperties, consistent withresyncanddatabase.