OpenTelemetry Rust SDK¶
本文采用 SDK Instrumentation:在应用代码中初始化 SDK、创建 Span 并配置 Exporter,通过 DataKit 将链路发送到 观测云。这不是零代码注入,安装依赖或设置环境变量不会自动采集所有框架调用。本文仅启用 Trace,不涉及 Kubernetes。
前置条件¶
- 安装 Rust stable 工具链和 Cargo;以下固定使用 OpenTelemetry
0.31.0,建议使用当前稳定工具链,并将Cargo.lock纳入应用版本管理。 - 示例使用同步
main、阻塞 HTTP 客户端和后台批量导出线程,不需要 Tokio。 - 已安装 DataKit,并使用目标工作空间的安装命令配置好上报地址和 Token;应用可访问 DataKit HTTP 端口
9529。
一、开启 OpenTelemetry 采集器¶
在 DataKit 主机上进入配置目录。仅在配置不存在时复制示例,已有文件请直接调整:
确认 opentelemetry.conf 中包含以下配置。自定义标签通过 customer_tags 保留:
[[inputs.opentelemetry]]
customer_tags = ["team", "app.operation"]
[inputs.opentelemetry.http]
http_status_ok = 200
trace_api = "/otel/v1/traces"
metric_api = "/otel/v1/metrics"
logs_api = "/otel/v1/logs"
本机接入使用 127.0.0.1:9529。跨主机接入时,在 DataKit 主配置 datakit.conf 的 [http_api].listen 中设置应用可访问的监听地址,并限制网络访问范围。HTTP 监听地址不在采集器文件中设置。
重启并检查 DataKit:
/v1/ping 只验证 HTTP 服务可达,不代表链路已入库。完整说明参见 OpenTelemetry 采集器。DataKit 负责工作空间认证,示例应用不直接配置工作空间 Token。
二、应用接入 OpenTelemetry¶
安装依赖¶
在空目录中创建示例项目,然后将 Cargo.toml 设置为以下内容。已有项目请合并依赖,不要覆盖原有配置:
[package]
name = "otel-rust-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
opentelemetry = { version = "=0.31.0", default-features = false, features = ["trace"] }
opentelemetry_sdk = { version = "=0.31.0", default-features = false, features = ["trace"] }
opentelemetry-otlp = { version = "=0.31.0", default-features = false, features = ["trace", "http-proto", "reqwest-blocking-client"] }
初始化 SDK 并创建 Span¶
将以下内容保存为 src/main.rs。SDK 在启动时初始化一次,checkout 下创建子 Span db.lookup,退出前等待批量导出:
use opentelemetry::{
global,
trace::{TraceContextExt, Tracer},
KeyValue,
};
use opentelemetry_otlp::{Protocol, SpanExporter, WithExportConfig};
use opentelemetry_sdk::{
propagation::TraceContextPropagator,
trace::{Sampler, SdkTracerProvider},
Resource,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let exporter = SpanExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary)
.build()?;
let provider = SdkTracerProvider::builder()
.with_batch_exporter(exporter)
.with_resource(Resource::builder().build())
.with_sampler(Sampler::ParentBased(Box::new(
Sampler::TraceIdRatioBased(1.0),
)))
.build();
global::set_text_map_propagator(TraceContextPropagator::new());
global::set_tracer_provider(provider.clone());
let tracer = global::tracer("otel-rust-demo");
tracer.in_span("checkout", |_cx| {
tracer.in_span("db.lookup", |cx| {
cx.span().set_attribute(KeyValue::new("app.operation", "lookup"));
});
});
provider.shutdown()?;
Ok(())
}
构建与运行¶
在启动应用的同一终端配置以下参数。跨主机时将 127.0.0.1 替换为实际 DataKit 地址:
export OTEL_SERVICE_NAME="order-service"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=prod,service.version=1.0.0,team=backend"
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://127.0.0.1:9529/otel/v1/traces"
cargo run
第一次运行会下载并编译依赖;后续可执行 cargo build --release 构建生产二进制。长期服务应保留 Provider,在停止接收请求并结束正在处理的 Span 后调用 shutdown()。
三、数据上报参数¶
| 参数或配置 | 说明 |
|---|---|
OTEL_SERVICE_NAME |
service.name;示例使用 order-service,应设置为稳定的服务名。 |
OTEL_RESOURCE_ATTRIBUTES |
逗号分隔的资源属性。示例设置环境、版本和 team;自定义字段应加入 DataKit customer_tags。 |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
Trace 专用完整地址:http://127.0.0.1:9529/otel/v1/traces。优先于通用基础地址。 |
OTEL_EXPORTER_OTLP_ENDPOINT |
可选基础地址:http://127.0.0.1:9529/otel。未设置 Trace 专用地址时,由 Exporter 追加 /v1/traces。 |
OTEL_EXPORTER_OTLP_HEADERS |
可选 OTLP 请求头,格式为 key=value,key2=value2。只有接收端或代理要求认证时才配置。 |
本例用 .with_http() 和 Protocol::HttpBinary 在代码中选择 HTTP/Protobuf;修改 OTEL_EXPORTER_OTLP_PROTOCOL 不会把该示例自动切换到 gRPC。改用 gRPC 需要启用 grpc-tonic、改用 .with_tonic() 并提供合适的 Tokio 运行时。
采样在代码中配置为 ParentBased + 根链路比例 1.0,遵循父 Span 的采样决定。生产环境可把示例中的比例改为 0.1,约采样 10% 的根链路。本例显式设置采样器,不依赖 OTEL_TRACES_SAMPLER 或 OTEL_TRACES_SAMPLER_ARG。
示例显式创建 Trace 导出管道,OTEL_TRACES_EXPORTER 不负责选择或关闭它。未创建 Metric、Log Provider,因此不会因设置 OTEL_METRICS_EXPORTER 或 OTEL_LOGS_EXPORTER 就启用对应信号。日志可另行使用 DataKit 日志文件采集。
上下文传播与业务接入¶
本例注册 W3C TraceContext 传播器,但不会自动拦截网络请求。接入 HTTP/RPC 时,需要在服务端通过 Extractor 提取上游上下文并作为新 Span 的父级,在客户端通过 Injector 注入 traceparent、tracestate。同步示例中的 in_span 不应直接跨 .await 使用;异步任务应使用 FutureExt::with_context 等方式传播上下文。使用 tracing 的应用还需配置兼容版本的 tracing-opentelemetry Layer。
验证与排查¶
- 执行示例后,在 观测云 应用性能监测中按
order-service查询链路,确认有checkout与其子 Spandb.lookup。 - 无数据时,检查采集器是否启用、应用环境变量是否生效、HTTP 路径是否包含
/otel/v1/traces,以及 DataKit 与应用的导出错误。 - 确认 Span 已结束且 Provider 在退出前完成刷新。强制退出或使用根链路比例
0会导致无法看到预期数据;网络连通不等于导出成功。