Skip to main content

tdm_server_rust/telemetry/skywalking/
sw_propagation.rs

1//! sw8 与 W3C traceparent 传播
2
3use ::skywalking::trace::{
4    propagation::{
5        context::PropagationContext, decoder::decode_propagation, encoder::encode_propagation,
6    },
7    trace_context::TracingContext,
8};
9use axum::http::{HeaderMap, HeaderName, HeaderValue};
10use std::str::FromStr;
11
12/// sw8 请求头名
13pub const SW8_HEADER: &str = "sw8";
14
15/// 从 HTTP 头解析 SW 传播上下文
16pub fn extract_sw8(headers: &HeaderMap) -> Option<PropagationContext> {
17    let raw = headers.get(SW8_HEADER)?.to_str().ok()?;
18    decode_propagation(raw).ok()
19}
20
21/// 将 SW 上下文编码为 sw8 响应头
22pub fn inject_sw8(headers: &mut HeaderMap, ctx: &TracingContext, endpoint: &str, address: &str) {
23    let value = encode_propagation(ctx, endpoint, address);
24    if let Ok(name) = HeaderName::from_str(SW8_HEADER) {
25        if let Ok(val) = HeaderValue::from_str(&value) {
26            headers.insert(name, val);
27        }
28    }
29}
30
31/// 从 SW trace_id 构造 W3C traceparent
32pub fn inject_traceparent(headers: &mut HeaderMap, trace_id: &str) {
33    let padded = if trace_id.len() >= 32 {
34        &trace_id[..32]
35    } else {
36        return;
37    };
38    let tp = format!("00-{padded}-0000000000000001-01");
39    if let Ok(name) = HeaderName::from_str("traceparent") {
40        if let Ok(val) = HeaderValue::from_str(&tp) {
41            headers.insert(name, val);
42        }
43    }
44}
45
46/// 解析 W3C traceparent(暂不支持续链)
47pub fn extract_traceparent(_headers: &HeaderMap) -> Option<PropagationContext> {
48    None
49}
50
51/// 合并提取:sw8 优先,其次 traceparent
52pub fn extract_inbound(headers: &HeaderMap) -> Option<PropagationContext> {
53    extract_sw8(headers).or_else(|| extract_traceparent(headers))
54}
55
56/// 编码 sw8 字符串(供 reqwest 使用)
57pub fn encode_sw8_value(ctx: &TracingContext, endpoint: &str, address: &str) -> String {
58    encode_propagation(ctx, endpoint, address)
59}
60
61/// 为 reqwest 注入 traceparent
62pub fn inject_traceparent_reqwest(headers: &mut reqwest::header::HeaderMap, trace_id: &str) {
63    let padded = if trace_id.len() >= 32 {
64        &trace_id[..32]
65    } else {
66        return;
67    };
68    let tp = format!("00-{padded}-0000000000000001-01");
69    if let Ok(name) = reqwest::header::HeaderName::from_bytes(b"traceparent") {
70        if let Ok(val) = reqwest::header::HeaderValue::from_str(&tp) {
71            headers.insert(name, val);
72        }
73    }
74}