Rust分布式追踪库fastrace-jaeger的使用:高性能Jaeger集成与调用链监控

Rust分布式追踪库fastrace-jaeger的使用:高性能Jaeger集成与调用链监控

fastrace-jaeger是一个为Jaeger设计的Rust reporter,用于fastrace库。

依赖

[dependencies]
fastrace = "0.7"
fastrace-jaeger = "0.7"

设置Jaeger Agent

docker run --rm -d -p6831:6831/udp -p14268:14268 -p16686:16686 --name jaeger jaegertracing/all-in-one:latest

cargo run --example synchronous

Web UI可在本地16686端口访问

报告到Jaeger Agent

以下是内容中提供的示例代码:

use std::net::SocketAddr;

use fastrace::collector::Config;
use fastrace::prelude::*;

// 初始化reporter
let reporter =
    fastrace_jaeger::JaegerReporter::new("127.0.0.1:6831".parse().unwrap(), "asynchronous")
        .unwrap();
fastrace::set_reporter(reporter, Config::default());

{
    // 开始追踪
    let root = Span::root("root", SpanContext::random());
}

fastrace::flush();

完整示例Demo

下面是一个更完整的示例,展示如何在Rust应用中使用fastrace-jaeger进行分布式追踪:

use std::{net::SocketAddr, thread, time::Duration};

use fastrace::collector::Config;
use fastrace::prelude::*;

fn main() {
    // 初始化Jaeger reporter
    let reporter = fastrace_jaeger::JaegerReporter::new(
        "127.0.0.1:6831".parse().unwrap(),  // Jaeger agent地址
        "example_service"                   // 服务名称
    ).unwrap();
    
    // 设置全局reporter
    fastrace::set_reporter(reporter, Config::default());

    // 创建根span
    let root = Span::root("root_operation", SpanContext::random());
    
    // 在根span下执行操作
    {
        let _guard = root.enter();  // 进入span上下文
        
        // 模拟一些工作
        thread::sleep(Duration::from_millis(100));
        
        // 创建子span
        let child = Span::child("child_operation", &root);
        {
            let _guard = child.enter();
            
            // 模拟一些子操作
            thread::sleep(Duration::from_millis(50));
            
            // 可以添加自定义标签
            child.set_tag("status", "success");
        }
        
        // 另一个子span
        let child2 = Span::child("second_operation", &root);
        {
            let _guard = child2.enter();
            
            // 模拟失败操作
            thread::sleep(Duration::from_millis(75));
            child2.set_tag("status", "failed");
            child2.set_tag("error", "timeout");
        }
    }
    
    // 确保所有span都被发送到Jaeger
    fastrace::flush();
    
    println!("Tracing data sent to Jaeger");
}

这个示例展示了:

  1. 初始化Jaeger reporter
  2. 创建根span和子span
  3. 添加自定义标签
  4. 模拟不同操作耗时
  5. 最后flush确保数据发送

要运行此示例,需要先启动Jaeger容器,然后将代码中的服务名称和Jaeger地址修改为你的实际配置。


1 回复

以下是关于fastrace-jaeger分布式追踪库的完整示例代码,基于您提供的内容整理:

use fastrace_jaeger::{Tracer, Config, span::{Span, SpanContext}};
use reqwest::header::HeaderMap;
use tokio;

// 完整的微服务追踪示例
#[tokio::main]
async fn main() {
    // 1. 初始化Jaeger追踪器
    let config = Config::new("order_service")
        .with_agent_endpoint("127.0.0.1:6831")
        .with_sampling_rate(0.8)  // 80%采样率
        .with_default_tags(vec![
            ("environment", "staging"),
            ("service.version", "1.0.0")
        ]);
    
    let _tracer = Tracer::init(config).expect("Failed to initialize tracer");

    // 模拟处理订单请求
    process_order("12345").await;
    
    // 模拟跨服务调用
    call_payment_service().await;
}

// 处理订单的函数
async fn process_order(order_id: &str) {
    // 创建根span
    let order_span = Span::start("process_order");
    
    // 添加订单ID标签
    order_span.tag("order.id", order_id);
    order_span.log(format!("开始处理订单 {}", order_id));
    
    // 模拟处理步骤
    validate_order(&order_span).await;
    check_inventory(&order_span).await;
    
    order_span.log("订单处理完成");
    order_span.finish();
}

async fn validate_order(parent: &Span) {
    let validate_span = parent.child("validate_order");
    
    // 模拟验证逻辑
    tokio::time::sleep(std::time::Duration::from_millis(20)).await;
    
    validate_span.tag("validation.status", "passed");
    validate_span.log("订单验证成功");
    
    validate_span.finish();
}

async fn check_inventory(parent: &Span) {
    let inventory_span = parent.child("check_inventory");
    
    // 模拟库存检查
    tokio::time::sleep(std::time::Duration::from_millis(30)).await;
    
    inventory_span.tag("inventory.status", "available");
    inventory_span.log("库存检查完成");
    
    inventory_span.finish();
}

// 模拟跨服务调用
async fn call_payment_service() {
    let payment_span = Span::start("call_payment_service");
    
    // 获取并注入上下文
    let context = payment_span.context();
    let mut headers = HeaderMap::new();
    context.inject_http_headers(&mut headers);
    
    // 模拟HTTP调用
    let client = reqwest::Client::new();
    let _ = client.post("http://payment-service/charge")
        .headers(headers)
        .send()
        .await;
    
    payment_span.finish();
}

// 模拟支付服务处理
async fn handle_payment_request(headers: &HeaderMap) {
    let context = SpanContext::extract_http_headers(headers)
        .unwrap_or_else(SpanContext::new);
    
    let payment_span = Span::continue_from("process_payment", context);
    
    // 处理支付逻辑...
    tokio::time::sleep(std::time::Duration::from_millis(40)).await;
    
    payment_span.tag("payment.status", "completed");
    payment_span.finish();
}

这个完整示例演示了:

  1. Jaeger追踪器的初始化配置
  2. 创建嵌套的span结构
  3. 添加标签和日志信息
  4. 跨服务调用的上下文传播
  5. 完整的异步操作支持

代码中包含了详细的注释说明每个关键步骤的作用。您可以根据实际需求调整采样率、默认标签等配置参数。

回到顶部