Skip to content

Commit c883b63

Browse files
authored
Handle 8 byte trace ids (#365)
Nginx uses 8 byte trace ids whereas OpenCensus expects trace ids which are 16 bytes. When we encounter an 8 byte trace id, we discard it, breaking the trace tree. When reading trace id headers, we now left-pad trace ids with 0s to 16 bytes. This is consistent with the way that OpenCensus handles trace ids less than 16 bytes: https://github.com/census-instrumentation/opencensus-go/blob/master/plugin/ochttp/propagation/b3/b3.go#L66 We also now log the appropriate error when we fail to emit a span. This will allow us to distinguish between the scenario when the span receiver has been dropped vs when span conversion fails. Signed-off-by: Alex Leong <[email protected]>
1 parent 4c3d706 commit c883b63

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

lib/linkerd2-trace-context/src/layer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ where
178178
span.end = SystemTime::now();
179179
response_labels(&mut span.labels, &inner);
180180
trace!(message = "emitting span", ?span);
181-
if sink.try_send(span).is_err() {
182-
warn!("span dropped due to backpressure");
181+
if let Err(error) = sink.try_send(span) {
182+
warn!(message = "span dropped", %error);
183183
}
184184
}
185185
Ok(Async::Ready(inner))

lib/linkerd2-trace-context/src/propagation.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ fn increment_grpc_span_id<B>(request: &mut http::Request<B>, context: &TraceCont
179179
}
180180

181181
fn unpack_http_trace_context<B>(request: &http::Request<B>) -> Option<TraceContext> {
182-
let parent_id = parse_header_id(request, HTTP_SPAN_ID_HEADER)?;
183-
let trace_id = parse_header_id(request, HTTP_TRACE_ID_HEADER)?;
182+
let parent_id = parse_header_id(request, HTTP_SPAN_ID_HEADER, 8)?;
183+
let trace_id = parse_header_id(request, HTTP_TRACE_ID_HEADER, 16)?;
184184
let flags = match get_header_str(request, HTTP_SAMPLED_HEADER) {
185185
Some("1") => Flags(1),
186186
_ => Flags(0),
@@ -215,10 +215,20 @@ fn get_header_str<'a, B>(request: &'a http::Request<B>, header: &str) -> Option<
215215
.ok()
216216
}
217217

218-
fn parse_header_id<B>(request: &http::Request<B>, header: &str) -> Option<Id> {
218+
fn parse_header_id<B>(request: &http::Request<B>, header: &str, pad_to: usize) -> Option<Id> {
219219
let header_value = get_header_str(request, header)?;
220220
hex::decode(header_value)
221-
.map(|data| Id(data))
221+
.map(|mut data| {
222+
if data.len() < pad_to {
223+
let padding = pad_to - data.len();
224+
let mut padded = Vec::with_capacity(padding);
225+
padded.resize(padding, 0u8);
226+
padded.append(&mut data);
227+
Id(padded)
228+
} else {
229+
Id(data)
230+
}
231+
})
222232
.map_err(|e| warn!("Header {} does not contain a hex value: {}", header, e))
223233
.ok()
224234
}

0 commit comments

Comments
 (0)