fix(sinks): use real wire bytes for OTLP batch sizing in the http sink#25882
Draft
vladimir-dd wants to merge 1 commit into
Draft
fix(sinks): use real wire bytes for OTLP batch sizing in the http sink#25882vladimir-dd wants to merge 1 commit into
vladimir-dd wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HttpBatchSizer::size()(used by the generichttpsink, and by extension theopentelemetrysink which wraps it) falls back toEvent::size_of()for any serializer it doesn't special-case. For the OTLP protobuf serializer, that in-memorysize_of()estimate overstates the real wire size by roughly an order of magnitude, because it's sizing the much larger JSON-shapedEvent::Logrepresentation rather than the compact protobuf payload actually sent.Since
max_bytesbatch accounting is driven by this estimate, batches close far earlier than the configured byte budget intends — in a production deployment we measured this causing ~6.6x more HTTP requests per second than the byte cap should have allowed for a given event stream, because each batch was hitting the (over-estimated) size ceiling long before it reached the real 380KB configured max.This PR adds an OTLP-specific branch to
HttpBatchSizer::size()that clones the configured serializer and actually encodes the event to get its true protobuf-encoded length, falling back tosize_of()only if encoding fails. This mirrors exactly what the real per-request encoder does, so batch-close decisions now reflect the real wire size.Why not just special-case a cheaper estimate?
OTLP protobuf encoding doesn't have a cheap structural shortcut analogous to JSON's estimated-size helpers — arbitrary numbers of repeated fields, varint-encoded lengths, and attribute maps mean an accurate estimate essentially requires doing the encode. Encoding here is cheap in practice (Arc-backed clones of the serializer/item, no additional allocation churn beyond the actual encode buffer), and it's the same work the request path does moments later anyway.
Test plan
otlp_batch_size_matches_real_wire_bytes_and_beats_size_of) asserting the sizer's reported size exactly matches a real OTLP-protobuf encode of the same event, and is meaningfully smaller thansize_of().