Skip to content

Commit e99034b

Browse files
authored
Fix varint length calculation in OTel payloads (#436)
* Fix varint length calculation * changelog * clippy
1 parent 9500fe8 commit e99034b

6 files changed

Lines changed: 40 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
## Fixed
9+
- Fix OpenTelemetry message length calculation for some messages.
810

911
## [0.12.0]
1012
## Changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Seeds for failure cases proptest has generated in the past. It is
2+
# automatically read and these particular cases re-run before any
3+
# novel cases are generated.
4+
#
5+
# It is recommended to check this file in to source control so that
6+
# everyone who runs the test benefits from these saved cases.
7+
cc 39803632d5c6543a1f796ab17d44b86bfadb85fdc0a0d1f851c66c75365959f1 # shrinks to seed = 11374604432742766758, max_bytes = 214

src/payload.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,25 @@ impl Serialize for Payload {
163163
}
164164
}
165165

166+
/// Calculates the quotient of `lhs` and `rhs`, rounding the result towards
167+
/// positive infinity.
168+
///
169+
/// Adapted from rustc `int_roundings` implementation. Replace upon
170+
/// stabilization: <https://github.com/rust-lang/rust/issues/88581>
171+
///
172+
/// # Panics
173+
///
174+
/// This function will panic if `rhs` is 0 or the division results in overflow.
175+
const fn div_ceil(lhs: usize, rhs: usize) -> usize {
176+
let d = lhs / rhs;
177+
let r = lhs % rhs;
178+
if r > 0 && rhs > 0 {
179+
d + 1
180+
} else {
181+
d
182+
}
183+
}
184+
166185
#[cfg(test)]
167186
mod test {
168187
use proptest::prelude::*;

src/payload/opentelemetry_log.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ impl Serialize for OpentelemetryLogs {
9797
rng.fill_bytes(&mut entropy);
9898
let mut unstructured = Unstructured::new(&entropy);
9999

100-
// An Export*ServiceRequest message has ~5 bytes of fixed values and
101-
// includes a varint-encoded message length. Use the worst case for this
102-
// length value.
103-
let bytes_remaining = max_bytes.checked_sub(5 + max_bytes / 0x7F);
100+
// An Export*ServiceRequest message has 5 bytes of fixed values plus
101+
// a varint-encoded message length field. The worst case for the message
102+
// length field is the max message size divided by 0x7F.
103+
let bytes_remaining = max_bytes.checked_sub(5 + super::div_ceil(max_bytes, 0x7F));
104104
let mut bytes_remaining = if let Some(val) = bytes_remaining {
105105
val
106106
} else {

src/payload/opentelemetry_metric.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,10 @@ impl Serialize for OpentelemetryMetrics {
186186
rng.fill_bytes(&mut entropy);
187187
let mut unstructured = Unstructured::new(&entropy);
188188

189-
// An Export*ServiceRequest message has ~5 bytes of fixed values and
190-
// includes a varint-encoded message length. Use the worst case for this
191-
// length value.
192-
let bytes_remaining = max_bytes.checked_sub(4 + 1 + max_bytes / 0x7F);
189+
// An Export*ServiceRequest message has 5 bytes of fixed values plus
190+
// a varint-encoded message length field. The worst case for the message
191+
// length field is the max message size divided by 0x7F.
192+
let bytes_remaining = max_bytes.checked_sub(5 + super::div_ceil(max_bytes, 0x7F));
193193
let mut bytes_remaining = if let Some(val) = bytes_remaining {
194194
val
195195
} else {

src/payload/opentelemetry_trace.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ impl Serialize for OpentelemetryTraces {
109109
rng.fill_bytes(&mut entropy);
110110
let mut unstructured = Unstructured::new(&entropy);
111111

112-
// An Export*ServiceRequest message has ~5 bytes of fixed values and
113-
// includes a varint-encoded message length. Use the worst case for this
114-
// length value.
115-
let bytes_remaining = max_bytes.checked_sub(5 + max_bytes / 0x7F);
112+
// An Export*ServiceRequest message has 5 bytes of fixed values plus
113+
// a varint-encoded message length field. The worst case for the message
114+
// length field is the max message size divided by 0x7F.
115+
let bytes_remaining = max_bytes.checked_sub(5 + super::div_ceil(max_bytes, 0x7F));
116116
let mut bytes_remaining = if let Some(val) = bytes_remaining {
117117
val
118118
} else {

0 commit comments

Comments
 (0)