Skip to content

Commit

Permalink
Handle 8 byte trace ids (#365)
Browse files Browse the repository at this point in the history
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 <alex@buoyant.io>
  • Loading branch information
adleong authored Oct 1, 2019
1 parent 4c3d706 commit c883b63
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
4 changes: 2 additions & 2 deletions lib/linkerd2-trace-context/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ where
span.end = SystemTime::now();
response_labels(&mut span.labels, &inner);
trace!(message = "emitting span", ?span);
if sink.try_send(span).is_err() {
warn!("span dropped due to backpressure");
if let Err(error) = sink.try_send(span) {
warn!(message = "span dropped", %error);
}
}
Ok(Async::Ready(inner))
Expand Down
18 changes: 14 additions & 4 deletions lib/linkerd2-trace-context/src/propagation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ fn increment_grpc_span_id<B>(request: &mut http::Request<B>, context: &TraceCont
}

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

fn parse_header_id<B>(request: &http::Request<B>, header: &str) -> Option<Id> {
fn parse_header_id<B>(request: &http::Request<B>, header: &str, pad_to: usize) -> Option<Id> {
let header_value = get_header_str(request, header)?;
hex::decode(header_value)
.map(|data| Id(data))
.map(|mut data| {
if data.len() < pad_to {
let padding = pad_to - data.len();
let mut padded = Vec::with_capacity(padding);
padded.resize(padding, 0u8);
padded.append(&mut data);
Id(padded)
} else {
Id(data)
}
})
.map_err(|e| warn!("Header {} does not contain a hex value: {}", header, e))
.ok()
}
Expand Down

0 comments on commit c883b63

Please sign in to comment.