envoyproxy / envoyproxy/gateway
Per-route downstream request counters for non-upstream traffic (ext_proc redirects, direct responses)
- Dominant language
- Go
- Stars
- 3k
- Forks
- 864
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 140
Description
## Description
Currently, Envoy Gateway only emits per-route metrics for requests that reach an upstream cluster (`vhost.*.route.*.upstream_rq_*`). Requests handled entirely within Envoy — via ext_proc, direct responses, or any filter returning early — are invisible at the route level.
Downstream metrics (`envoy_http_downstream_rq_*`) exist but are scoped only to the HTTP connection manager / listener level (`http_conn_manager_prefix`), with no per-route granularity.
## Problem
From an observability standpoint, a significant portion of traffic can disappear from route-level monitoring:
- **ext_proc returning early** (HTTP 302 redirects, 401 denials, 403 rejections)
- **Direct responses** configured at the route level (redirects, fixed responses)
- **Any filter** that intercepts and responds before the router filter reaches upstream
These requests are fully handled by Envoy but generate zero per-route metrics. Operators lose visibility into redirect rates per route, auth denial rates per route, and other filter-driven behavior that never hits upstream.
## Use Case
We run Envoy 1.38 with Envoy Gateway. Our ext_proc filters handle auth, request validation, and canary routing. When ext_proc returns a 302 redirect, we have no per-route metric to track how many redirects a specific route is generating. The only way to get this data today is via access logs or external systems.
## Proposal
Add per-route downstream counters at the virtual host / route level, covering all requests that match a route, regardless of whether they reach upstream. For example:
```
vhost..route..downstream_rq_total
vhost..route..downstream_rq_2xx
vhost..route..downstream_rq_3xx
vhost..route..downstream_rq_4xx
vhost..route..downstream_rq_5xx
```
These would be incremented at the router filter when the final response is sent, based on the matched route, independently of whether the request was forwarded to an upstream cluster.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the router filter and the existing per-route upstream request counters, then trace how final responses are classified for requests handled by ext_proc, direct responses, or other early-returning filters. Done means matched routes expose downstream total and status-class counters for both upstream and non-upstream traffic, with tests covering redirects, denials, direct responses, and forwarded requests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend-api-design, observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100