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