3 releases

0.11.0-alpha.21 Oct 21, 2024
0.11.0-alpha.20 Oct 20, 2024
0.11.0-alpha.19 Oct 16, 2024

#147 in Debugging

Download history 437/week @ 2024-10-15 84/week @ 2024-10-22 7/week @ 2024-10-29 10/week @ 2024-11-05

538 downloads per month

MIT/Apache

2.5MB
7K SLoC

Rust 5K SLoC // 0.2% comments JavaScript 2K SLoC // 0.0% comments

emit_traceparent

traceparent

Current docs

Support trace propagation and sampling via W3C traceparents.


lib.rs:

Distributed trace context for emit.

This library implements the W3C trace context standard over emit's tracing functionality. Trace context is propagated as a traceparent in a simple text format. Here's an example of a traceparent:

00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

It includes:

  • A version: 00.
  • A trace id: 4bf92f3577b34da6a3ce929d0e0e4736.
  • A span id: 00f067aa0ba902b7.
  • A set of trace flags: 01 (sampled).

Getting started

Add emit and emit_traceparent to your Cargo.toml:

[dependencies.emit]
version = "0.11.0-alpha.21"

[dependencies.emit_traceparent]
version = "0.11.0-alpha.21"

Initialize emit using the setup or setup_with_sampler functions from this library:

fn main() {
let rt = emit_traceparent::setup()
.emit_to(emit_term::stdout())
.init();

// Your app code goes here

rt.blocking_flush(std::time::Duration::from_secs(30));
}

Incoming traceparent

When a request arrives, parse a Traceparent from it and push it onto the current context. Handle the request in the returned emit::Frame to make trace context correlate with the upstream service:

let traceparent = emit_traceparent::Traceparent::try_from_str("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
.unwrap_or_else(|_| emit_traceparent::Traceparent::current());

// 2. Push the traceparent onto the context and execute your handler within it
traceparent.push().call(handle_request);

#[emit::span("incoming request")]
fn handle_request() {
// Your code goes here
}

Outgoing traceparent

When making an outgoing request, get the current Traceparent and format it into a header for the downstream service:

let mut headers = HashMap::<String, String>::new();

// 1. Get the current traceparent
let traceparent = emit_traceparent::Traceparent::current();

if traceparent.is_valid() {
// 2. Add the traceparent to the outgoing request
headers.insert("traceparent".into(), traceparent.to_string());
}

Traceparent and SpanCtxt

emit stores the active span context as an emit::SpanCtxt in its emit::Ctxt, which it generates in [macro@emit::span] for you. SpanCtxt doesn't have the concept of sampling, so if it exists then it's sampled. When in use, the Traceparent type defined by this library becomes the source of truth for the SpanCtxt. If the current Traceparent is not sampled, then no SpanCtxt will be returned.

Only the span id on incoming SpanCtxts created by [macro@emit::span] are respected. The current Traceparent overrides any incoming trace ids or span parents.

Dependencies