#axum #fastrace #tracing #propagation #traceparent

fastrace-axum

A axum instrument for propagating trace context for fastrace

1 unstable release

new 0.1.0 Mar 27, 2025

#1118 in Debugging

Download history 117/week @ 2025-03-24

117 downloads per month

Apache-2.0

24KB

fastrace-axum

Crates.io Documentation MSRV 1.80.0 CI Status License

fastrace-axum is a middleware library that connects fastrace, a distributed tracing library, with axum, a gRPC framework for Rust. This integration enables seamless trace context propagation across microservice boundaries in gRPC-based applications.

What is Context Propagation?

Context propagation is a fundamental concept in distributed tracing that enables the correlation of operations spanning multiple services. When a request moves from one service to another, trace context information needs to be passed along, ensuring that all operations are recorded as part of the same trace.

fastrace-axum implements the W3C Trace Context standard for propagating trace information between services. This ensures compatibility with other tracing systems that follow the same standard.

Features

  • 🔄 Automatic Context Propagation: Automatically extract trace context from HTTP requests.
  • 🌉 Seamless Integration: Works seamlessly with the fastrace library for complete distributed tracing.
  • 📊 Full Compatibility: Works with fastrace's collection and reporting capabilities.

Usage

Server Integration

Add fastrace-axum to your Cargo.toml:

[dependencies]
fastrace = "0.7"
fastrace-axum = "0.1"

Apply the FastraceLayer to your axum server:

use fastrace::collector::Config;
use fastrace::collector::ConsoleReporter;

#[tokio::main]
async fn main() {
    // Configurate fastrace reporter.
    fastrace::set_reporter(ConsoleReporter, Config::default());

    let app = axum::Router::new()
        .route("/ping", axum::routing::get(ping))
        // Add a the FastraceLayer to routes.
        // The layer extracts trace context from incoming requests.
        .layer(fastrace_axum::FastraceLayer);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

#[fastrace::trace] // Trace individual handlers.
async fn ping() -> &'static str {
    "pong"
}

Client Usage with fastrace-reqwest

To propagate trace context from clients to your Poem service:

use fastrace::prelude::*;
use reqwest::Client;

#[fastrace::trace]
async fn send_request() {
    let client = Client::new();
    let response = client
        .get("http://your-poem-service/endpoint")
        .headers(fastrace_reqwest::traceparent_headers()) // Adds traceparent header.
        .send()
        .await
        .unwrap();
    
    // Process response...
}

Example

Check out the examples directory for a complete ping/pong service example that demonstrates both client and server tracing.

To run the example:

  1. Start the server:

    cargo run --example server
    
  2. In another terminal, run the client:

    cargo run --example client
    

Both applications will output trace information showing the request flow, including the propagated context.

How It Works

  1. When a server receives the request, FastraceLayer extracts the trace context from the traceparent header and creates a new span as a child of the received context.
  2. If no trace context is provided, the server creates a new root span.

This process ensures that all operations across services are properly connected in the resulting trace, providing visibility into the entire request lifecycle.

License

This project is licensed under the Apache-2.0 license.

Dependencies

~2.7–8MB
~65K SLoC