Skip to content

feat: expose gRPC access log buffering on the ALS and OpenTelemetry sinks - #9725

Open
xiongzubiao wants to merge 1 commit into
envoyproxy:mainfrom
xiongzubiao:feat/accesslog-grpc-buffer
Open

feat: expose gRPC access log buffering on the ALS and OpenTelemetry sinks#9725
xiongzubiao wants to merge 1 commit into
envoyproxy:mainfrom
xiongzubiao:feat/accesslog-grpc-buffer

Conversation

@xiongzubiao

@xiongzubiao xiongzubiao commented Aug 11, 2026

Copy link
Copy Markdown

What this PR does / why we need it:

Envoy Gateway builds CommonGrpcAccessLogConfig for the OpenTelemetry and ALS access log sinks with only LogName, GrpcService and TransportApiVersion set, so buffer_flush_interval and buffer_size_bytes always take Envoy's defaults of 1s and 16384 bytes and nothing on ProxyAccessLogSetting can change them. This adds a buffer field carrying flushInterval and sizeBytes to both gRPC sinks.

Placement. The issue asked whether this belongs per-sink or per-settings entry and offered both. This PR puts it per-sink: the setting is meaningless for File sinks, and one settings entry can carry several sinks whose backends differ in availability, so a single knob could not express that. GRPCAccessLogBufferSettings is declared once and referenced from both sink types.

ALS. Also left open in the issue — yes, it applies. Both sinks feed the same CommonGrpcAccessLogConfig, and applyAccessLogBuffer runs before the switch als.Type, so ALS HTTP and TCP are both covered.

Backward compatibility. Unset fields are never written, so existing configurations produce byte-identical xDS. Verified by regenerating every golden against a stashed tree.

Range checking. Envoy carries buffer_size_bytes as a 32-bit unsigned integer. A CEL bound rejecting 4Gi and above at admission is not possible here: quantity() on an x-kubernetes-int-or-string field exceeds the CRD validation cost budget by 63x, and MaxLength does not help because the estimator treats the value as dynamic. The range is checked during translation instead, matching how BufferLimit and the other Quantity byte-size fields already behave. Zero and negative values are rejected there too, since the pattern constrains only the string form of an int-or-string field.

Status message change, please review. processAccessLog has five error returns and only two concern backendRefs, so "Invalid access log backendRefs in the referenced EnvoyProxy" already misreported invalid CEL match expressions and would now also misreport buffer settings. It is reworded to "Invalid access log configuration in the referenced EnvoyProxy" and carries its own release note. processTracing and processMetrics each have a single backendRefs error return, so their wording is unchanged. This is the one change outside the strict scope of the issue.

A practical caveat the issue does not state. Entries survive a sink outage only while they stay buffered, and a flush that fires while the sink is unreachable loses the batch it was carrying. Measured on Envoy 1.40.0-dev with a fault proxy in front of the collector: with flushInterval: 60s across a 20s outage, sizeBytes: 4Mi retained 20 of 20 entries while 512 retained 5 of 20. At the default flushInterval: 1s a flush is attempted every second, so raising sizeBytes alone does not widen that window. The task documentation describes the two settings as the pair they are.

Which issue(s) this PR fixes:

Fixes #9723


PR Checklist

  • Authorship & ownership: Coding agents / AI assistants are welcome, but I have reviewed every change, understand how and why it works, can explain and maintain it, and take full responsibility for this PR. I have not submitted generated output I do not understand.
  • DCO: All commits are signed off (git commit -s). See DCO: Sign your work.
  • API agreed first: If this PR contains API changes (changes under /api), the API was discussed and agreed before the implementation. The API change can be in a separate PR, or in the same PR, but the API must be agreed before implementation. N/A if this PR does not contain API changes.
  • Required checks pass: make generate gen-check, make lint, and the unit-test/coverage build pass. (Flaky e2e failures are not considered breakages, but gen-check, lint, and coverage MUST pass.)
  • Tests added/updated: New/changed code is covered by appropriate tests. N/A if this PR does not contain code changes.
  • Docs: User-facing changes update the docs, either in this PR or a follow-up PR. N/A if this PR does not contain user-facing changes.
  • Release notes: For any non-trivial change, added a release-note fragment under release-notes/current/<section>/<pr-number>-<slug>.md (see release-notes/current/README.md for sections and naming). N/A if this PR does not contain non-trivial changes.
  • Generated files committed: Ran make gen-check and committed the result if API/helm charts/modules changed.
  • Scope & compatibility: The PR is reasonably scoped (no unrelated changes) and preserves backward compatibility, or any breaking change is called out above and documented in release-notes/current/breaking_changes/.
  • Codex review: Requested a Codex review and addressed all of its comments.
  • Copilot review: Requested a Copilot review and addressed all of its comments. N/A: adding a reviewer needs triage permission on this repo, which an external fork contributor does not have. A maintainer is welcome to add Copilot.

API agreed first — the issue proposed exposing these two fields and a maintainer replied "sound reasonable to me, feel free to raise PR to improve it", but the API shape was explicitly left open there (per-sink vs per-settings entry). So the concept was agreed and the shape was not. Flagging rather than claiming agreement; happy to split the API into its own PR if that is preferred.

@xiongzubiao
xiongzubiao requested a review from a team as a code owner August 11, 2026 18:33
@netlify

netlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 9a893d1
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6a918a4f86ab9a00088fa712
😎 Deploy Preview https://deploy-preview-9725--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@xiongzubiao
xiongzubiao force-pushed the feat/accesslog-grpc-buffer branch from c9abf61 to 16bb949 Compare August 11, 2026 19:04
@xiongzubiao

Copy link
Copy Markdown
Author

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 16bb9497c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@zirain zirain added this to the v1.10.0-rc.1 Release milestone Aug 28, 2026
…inks

Envoy Gateway built CommonGrpcAccessLogConfig with only LogName, GrpcService
and TransportApiVersion set, so buffer_flush_interval and buffer_size_bytes
always took Envoy's defaults of 1s and 16384 bytes, and nothing on
ProxyAccessLogSetting could change them.

Add a `buffer` field carrying `flushInterval` and `sizeBytes` to both gRPC
sinks. It sits on the sink rather than on the ProxyAccessLogSetting entry
because the setting is meaningless for File sinks, and because one settings
entry can carry several sinks whose backends differ in availability. Both
sinks feed the same CommonGrpcAccessLogConfig, so both get it.

Unset fields are not written, so existing configurations produce byte
identical xDS.

Envoy carries buffer_size_bytes as a 32-bit unsigned integer. A CEL bound
rejecting 4Gi and above at admission is not possible here: quantity() on an
x-kubernetes-int-or-string field exceeds the CRD validation cost budget by
63x, and MaxLength does not help because the estimator treats the value as
dynamic. The range is checked during translation instead, matching how
BufferLimit and the other Quantity byte-size fields already behave. Zero and
negative values are rejected there too, since the pattern constrains only the
string form of this int-or-string field.

Also reword the Gateway status message for access log translation failures
from "Invalid access log backendRefs in the referenced EnvoyProxy" to
"Invalid access log configuration in the referenced EnvoyProxy".
processAccessLog has five error returns and only two concern backendRefs; the
message already misreported invalid CEL match expressions, and would now also
misreport buffer settings. processTracing and processMetrics each have a
single backendRefs error return, so their wording is left alone.

e2e coverage is added for both gRPC sinks, following the existing per-sink
access log tests. Verified against a kind cluster: the running proxy's
config_dump reports the configured values on both the otel_envoy_accesslog
and ALS loggers.

The task docs describe the two settings as the pair they are. Entries survive
a sink outage only while they stay buffered, so flushInterval has to outlast
the outage and sizeBytes has to hold the entries arriving during it. At the
1s default a flush is attempted every second, so raising sizeBytes alone does
not widen that window. Measured with a fault proxy in front of the collector:
with flushInterval 60s and a 20s outage, sizeBytes 4Mi delivered all 20
entries after recovery while 512 bytes delivered 5.

Signed-off-by: Zubiao Xiong <xiongzubiao@gmail.com>
@zirain
zirain force-pushed the feat/accesslog-grpc-buffer branch from 16bb949 to 9a893d1 Compare August 28, 2026 13:17
// Buffer defines how access log entries are buffered before being flushed to the
// access log service.
// +optional
Buffer *GRPCAccessLogBufferSettings `json:"buffer,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be more generic to support more options in the future?

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.

Expose gRPC access-log buffering (buffer_size_bytes / buffer_flush_interval) on ProxyAccessLogSetting

2 participants