---
title: "Custom Instrumentation"
url: https://docs.sentry.io/platforms/rust/guides/axum/tracing/trace-propagation/custom-instrumentation/
---

# Custom Instrumentation for Distributed Tracing for axum

On this page you will learn how to manually propagate trace information into and out of your Rust application.

To obtain trace headers from a span, use the `iter_headers()` method. Then pass these to the downstream service. If the communication happens over HTTP, it is recommended to attach all headers to the outgoing HTTP request.

For example when using the `reqwest` crate:

```rust
let client = reqwest::Client::new();

let mut request = client.get("downstream-url");
if let Some(span) = sentry::configure_scope(|scope| scope.get_span()) {
    for (k, v) in span.iter_headers() {
        request = request.header(k, v);
    }
}

let response = request.send().await?;
```

To create a span as a continuation of the trace retrieved from the upstream service, pass an iterator of the incoming headers to the transaction context:

```rust
// This needs to be a `impl Iterator<Item = (&str, &str)>` of header key/value pairs.
let headers = request.headers();
let tx_ctx = sentry::TransactionContext::continue_from_headers(
    "transaction name",
    "http.server",
    headers,
);
let transaction = sentry::start_transaction(tx_ctx);
```

For usage with the `tower` crate, the `SentryHttpLayer` handles trace continuations automatically when constructed via `SentryHttpLayer::with_transaction()`.
