Skip to content

cilium: defer response logging until stream completion#1879

Draft
nvibert wants to merge 1 commit intocilium:mainfrom
nvibert:feat/defer-response-access-log
Draft

cilium: defer response logging until stream completion#1879
nvibert wants to merge 1 commit intocilium:mainfrom
nvibert:feat/defer-response-access-log

Conversation

@nvibert
Copy link
Copy Markdown

@nvibert nvibert commented Apr 27, 2026

What

Defer the Cilium HTTP response access log entry until the response stream has actually completed, instead of emitting it from encodeHeaders().

The Cilium AccessFilter currently logs the response side from encodeHeaders(). That is too early: any response-side header mutation performed by a downstream filter (for example an Envoy ext_proc external processor that adds metadata headers on the response path) is not reflected in the access log entry that the Cilium agent consumes, even though the mutated headers reach the wire correctly.

This change moves the response log emission to stream completion:

  • encodeHeaders() records the response header map and only logs immediately if end_stream is true on headers.
  • encodeData() and encodeTrailers() are now implemented and call logResponse() when the stream ends.
  • onStreamComplete() acts as a final safety net.
  • A response_logged_ guard ensures the response log entry is emitted exactly once per stream regardless of which path triggers it.

Why

This is a prerequisite for surfacing ext_proc-injected response metadata through the Cilium access log bridge into Hubble. A concrete motivating use case is AI / LLM observability, where an external processor extracts model and token usage from the response body and exposes it as response headers (e.g. x-ai-input-tokens, x-ai-output-tokens, x-ai-total-tokens). Today these headers are visible on the wire but never make it into Hubble flow metadata.

Tests

  • New unit coverage in tests/accesslog_test.cc for deferred response logging on stream completion.
  • New integration coverage in tests/cilium_http_integration_test.cc validating that response-side headers mutated after encodeHeaders() are reflected in the access log entry consumed by Cilium.

Notes

  • Marking as draft to exercise CI and to validate the patch end-to-end against a real Cilium build before requesting review.
  • Rebased on top of latest origin/main (bdb8b53d).

@nvibert nvibert force-pushed the feat/defer-response-access-log branch 2 times, most recently from 60d73ec to 4c15e71 Compare April 27, 2026 13:10
The Cilium HTTP access log entry for the response side is currently
emitted from encodeHeaders(), before later stages of the response
stream complete. This means response-side header mutations performed
by downstream filters such as ext_proc are not reflected in the
access log entry that the Cilium agent consumes, even though they
reach the wire correctly.

Defer the response log entry until the response stream has actually
completed:

- encodeHeaders() now records the response header map and only emits
  the log entry immediately if end_stream is true on headers.
- encodeData() and encodeTrailers() are implemented and call
  logResponse() once the stream ends.
- onStreamComplete() acts as a final safety net.

A response_logged_ guard ensures the response log entry is emitted
exactly once per stream regardless of which code path triggers it.

This is a prerequisite for surfacing ext_proc-injected response
metadata (for example, AI usage headers such as token counts added
by an external processor on the response path) through the Cilium
access log bridge into Hubble.

Tests:

- New unit coverage in tests/accesslog_test.cc for deferred response
  logging on stream completion.
- New integration coverage in tests/cilium_http_integration_test.cc
  validating that response-side headers mutated after encodeHeaders()
  are reflected in the access log entry consumed by Cilium.

Signed-off-by: Nico Vibert <nvibert@cisco.com>
@nvibert nvibert force-pushed the feat/defer-response-access-log branch from 4c15e71 to ed791ec Compare April 27, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant