router: scope upstream HTTP filter chain to the connection manager stat prefix#45666
router: scope upstream HTTP filter chain to the connection manager stat prefix#45666fl0Lec wants to merge 2 commits into
Conversation
4413b6a to
f2f5ed0
Compare
|
/retest |
botengyao
left a comment
There was a problem hiding this comment.
thanks for working on it.
/wait
| upstream_filter_scope_ = context.scope().createScope(prefix); | ||
| upstream_ctx_ = std::make_unique<Upstream::UpstreamFactoryContextImpl>( | ||
| server_factory_ctx, context.initManager(), context.scope()); | ||
| server_factory_ctx, context.initManager(), *upstream_filter_scope_); |
There was a problem hiding this comment.
This is a behavior change, could you please add a runtime guard on it?
…at prefix
The router builds its upstream_http_filters chain at the root stats scope,
so upstream filters (e.g. the upstream RBAC filter) emit metrics with no
downstream context. The cluster-level upstream filter chain, by contrast,
is scoped to "cluster.<name>.".
Build the router's upstream filter chain under a stats scope that inherits
the connection manager's stat prefix ("http.<stat_prefix>."), which the
router already receives as stat_prefix, mirroring the cluster path. Upstream
filters configured via Router.upstream_http_filters now emit stats under
"http.<stat_prefix>." instead of the root scope.
Signed-off-by: Florent Lecoultre <florent.lecoultre@datadoghq.com>
Add runtime guard envoy.reloadable_features.router_upstream_filters_scoped_stat_prefix (enabled by default) around the new upstream filter chain stat scoping. When disabled, reverts to the legacy root-scope behavior for operators who need to preserve existing dashboard/alert configuration. Signed-off-by: Florent Lecoultre <florent.lecoultre@datadoghq.com>
f2f5ed0 to
878ba8b
Compare
|
/retest |
|
@botengyao gentle bump on this one |
There was a problem hiding this comment.
Thanks for working on this.
First, the current context.scope() is not root scope, it's filter chain scope with empty prefix.
Second, the current router's implementation actually correctly matches the downstream HTTP filters' implementation. The scope self has an empty prefix, and the parent's prefix is propagated to the filter factory by a string and the filter could optionally use it or not. (I actually agree that letting the parent create a prefixed scope is better design, then the sub filters needn't to care about the stat prefix. However, previous design works from the start of this project, even if we want to migrate, it should be done in a more smooth way).
It's more like the cluster's HTTP filter chain has an unexpected implementation.
Note, most of the HTTP filters will concatenate the parent prefix string http.example. to the own prefix and stat names and create the stats under the factory context's scope.
With these changes, it may result in unexpected stats names like: http.example.http.example.foo or cluster.example.cluster.example.foo when these filters are used as upstream filters.
That's say, we may need to update the cluster's implementation to match the router rather to update router.
cc @botengyao
|
Closing this in favor of #45987, which takes the approach suggested in review: instead of creating a sub-scope in the router, the fix is applied at the stats_prefix string level — passing the correct prefix to FilterChainHelper from both router.cc and upstream_impl.cc, and removing the EMPTY_STRING workaround in the upstream RBAC filter config. Thanks for the feedback that pointed in the right direction. |
Commit Message: router: scope upstream HTTP filter chain to the connection manager stat prefix
Additional Description:
Generative AI (Claude) was used to assist with this change; I have reviewed and understand all of the code.
The router builds its
upstream_http_filterschain at the root stats scope: inFilterConfig's constructor the upstreamFilterChainHelperis givencontext.scope()(the root scope) and a prefix derived fromcontext.scope().prefix()(empty). As a result, stats emitted by upstream HTTP filters configured viaRouter.upstream_http_filtershave no downstream context.By contrast, the cluster-level upstream filter chain (
HttpProtocolOptions.http_filters, built inupstream_impl.cc) is scoped tocluster.<name>..This change builds the router's upstream filter chain under a stats scope that inherits the connection manager's stat prefix (
http.<stat_prefix>.) — which the router already receives as thestat_prefixStatName— mirroring the cluster path. Filters that read their stats scope now emit stats underhttp.<stat_prefix>.instead of the root scope.Open question for maintainers: this changes the stat path for existing
upstream_http_filtersusers, so a runtime guard would normally be expected. However, the scope is chosen once at config-construction time (not on the request path), so areloadable_featuresguard does not map cleanly. Happy to gate it differently if preferred.Risk Level: Low (only affects the stats scope of
upstream_http_filters, a rarely-used feature; no data-plane behavior change).Testing:
//test/common/router:router_upstream_filter_testpasses;//source/common/router:router_libbuilds.Docs Changes: n/a
Release Notes: added (minor_behavior_changes).
Platform Specific Features: n/a