Title: access_log: expose selected route path matcher to logs, tracing, and Wasm
Description:
Envoy already selects a route and retains its path match specifier on RouteEntry (pathMatchCriterion().matcher() / matchType()). That string is not available to access logs, tracing substitution formatters, or Wasm get_property. Operators can log or name spans with the request path (%PATH%) or the route name (%ROUTE_NAME%), but not with the pattern that actually matched.
Desired behavior
After HTTP route selection, expose the selected route’s path specifier as:
- A substitution formatter command operator, analogous to
%ROUTE_NAME%, e.g. %ROUTE_PATH_MATCHER%, so it can be used in access log format strings and in HttpConnectionManager tracing operation / upstream_operation (Envoy Gateway telemetry.tracing.spanName).
- An xDS/CEL attribute, e.g.
xds.route_path_matcher (and optionally xds.route_path_match_type), so Wasm can read it via get_property and access logs/tags can use %CEL(...)% where CEL formatters are configured.
The request method is already available (%REQ(:method)%, request.method, :method). This request is only for the matched path pattern.
Example
Route match:
match:
safe_regex:
regex: "/rest/v1.0/status/[^/]+"
headers:
- name: ":method"
string_match:
exact: "GET"
Request: GET /rest/v1.0/status/401
Desired values:
%REQ(:method)% → GET (existing)
%ROUTE_PATH_MATCHER% / xds.route_path_matcher → /rest/v1.0/status/[^/]+
Desired tracing span / operation name:
%REQ(:method)% %ROUTE_PATH_MATCHER%
→ GET /rest/v1.0/status/[^/]+
Today the equivalent config using %PATH(NQ)% produces GET /rest/v1.0/status/401, which is high cardinality and not the matched route.
For exact and prefix routes, the same operator should return that specifier (/healthz, /api/v1/), not only safe_regex.
How it would be used
- Access logs: include the matched pattern next to
%PATH% so traffic can be aggregated by route pattern.
- Tracing: set HCM
tracing.operation to %REQ(:method)% %ROUTE_PATH_MATCHER% for stable span names.
- Wasm:
get_property({"xds", "route_path_matcher"}) (or the final agreed path) in HTTP Wasm filters after route selection.
A built-in command operator is important for tracing span names. %ROUTE_NAME% and %REQ(...)% work in tracing.operation; %CEL(...)% in that field is still incomplete (see #45447). Depending on CEL alone would not cover the span-name use case.
Suggested implementation (for discussion)
Read the existing C++ view after route selection:
stream_info.routeEntry()->pathMatchCriterion().matcher()
stream_info.routeEntry()->pathMatchCriterion().matchType()
This was added in #2531 for access-log / extension use, kept after #20649 / #20797, and is implemented for regex routes via path_matcher_->stringRepresentation(). It is not wired to substitution formatters, CEL xds.* attributes, or Wasm.
This should not be copied into per-request filter state. It is selected-route config, like xds.route_name.
Edge cases to document
- No selected route → empty /
- (same convention as %ROUTE_NAME%).
- Matcher-tree /
path_match_policy routes that report PathMatchType::None → empty string.
- High cardinality if used as a stat label; intended for logs, traces, and Wasm, not stats dimensions.
Title: access_log: expose selected route path matcher to logs, tracing, and Wasm
Description:
Envoy already selects a route and retains its path match specifier on
RouteEntry(pathMatchCriterion().matcher()/matchType()). That string is not available to access logs, tracing substitution formatters, or Wasmget_property. Operators can log or name spans with the request path (%PATH%) or the route name (%ROUTE_NAME%), but not with the pattern that actually matched.Desired behavior
After HTTP route selection, expose the selected route’s path specifier as:
%ROUTE_NAME%, e.g.%ROUTE_PATH_MATCHER%, so it can be used in access log format strings and inHttpConnectionManagertracingoperation/upstream_operation(Envoy Gatewaytelemetry.tracing.spanName).xds.route_path_matcher(and optionallyxds.route_path_match_type), so Wasm can read it viaget_propertyand access logs/tags can use%CEL(...)%where CEL formatters are configured.The request method is already available (
%REQ(:method)%,request.method,:method). This request is only for the matched path pattern.Example
Route match:
Request:
GET /rest/v1.0/status/401Desired values:
%REQ(:method)%→GET(existing)%ROUTE_PATH_MATCHER%/xds.route_path_matcher→/rest/v1.0/status/[^/]+Desired tracing span / operation name:
→
GET /rest/v1.0/status/[^/]+Today the equivalent config using
%PATH(NQ)%producesGET /rest/v1.0/status/401, which is high cardinality and not the matched route.For exact and prefix routes, the same operator should return that specifier (
/healthz,/api/v1/), not onlysafe_regex.How it would be used
%PATH%so traffic can be aggregated by route pattern.tracing.operationto%REQ(:method)% %ROUTE_PATH_MATCHER%for stable span names.get_property({"xds", "route_path_matcher"})(or the final agreed path) in HTTP Wasm filters after route selection.A built-in command operator is important for tracing span names.
%ROUTE_NAME%and%REQ(...)%work intracing.operation;%CEL(...)%in that field is still incomplete (see #45447). Depending on CEL alone would not cover the span-name use case.Suggested implementation (for discussion)
Read the existing C++ view after route selection:
stream_info.routeEntry()->pathMatchCriterion().matcher()stream_info.routeEntry()->pathMatchCriterion().matchType()This was added in #2531 for access-log / extension use, kept after #20649 / #20797, and is implemented for regex routes via
path_matcher_->stringRepresentation(). It is not wired to substitution formatters, CELxds.*attributes, or Wasm.This should not be copied into per-request filter state. It is selected-route config, like
xds.route_name.Edge cases to document
-(same convention as%ROUTE_NAME%).path_match_policyroutes that reportPathMatchType::None→ empty string.