9 个版本
0.1.1 | 2023 年 9 月 7 日 |
---|---|
0.1.0 | 2023 年 9 月 7 日 |
0.0.7 | 2023 年 4 月 3 日 |
0.0.1 | 2023 年 3 月 31 日 |
1220 在 Web 编程 中
每月下载 272 次
18KB
165 行
Datadog 为 Rust 服务提供跟踪和日志关联。
Datadog 为 Python 提供官方支持,包括各种 SDK 和其他工具(如 Python 的 ddtrace
库)用于在 Python 应用程序中进行跟踪和日志记录。
对于 Rust,他们没有类似的支持。但是,他们支持日志和跟踪的 OpenTelemetry 格式。此 crate 包含连接 OpenTelemetry 和 Datadog 之间差距所需的粘合剂。
功能
ddtrace
有以下功能
- 跟踪:构建发送跟踪到 Datadog 代理的 OpenTelemetry 跟踪器/层的工具
- 日志关联:将跟踪 ID 和跨度 ID 转换为 Datadog 本地格式并注入到
dd.trace_id
和dd.span_id
字段中的日志格式化程序 (更多信息) - 传播:一个实用函数,用于将 Datadog 传播者设置为全局传播者
- axum(通过
axum
功能启用):重新公开 axum-tracing-opentelemetry 的功能
完整示例
以下是一个使用 ddtrace
的示例,其中启用了 axum
功能,以设置一个将跟踪和日志发送到 Datadog 的 axum
服务。
use std::net::SocketAddr;
use std::time::Duration;
use axum::{routing::get, Router};
use ddtrace::axum::opentelemetry_tracing_layer;
use ddtrace::formatter::DatadogFormatter;
use ddtrace::set_global_propagator;
use ddtrace::tracer::{build_layer, TraceResult};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
#[tokio::main]
async fn main() -> TraceResult<()> {
let service_name = std::env::var("DD_SERVICE").unwrap_or("my-service".to_string());
let tracing_layer = build_layer(&service_name)?;
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::new(
std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()),
))
.with(
tracing_subscriber::fmt::layer()
.json()
.event_format(DatadogFormatter),
)
.with(tracing_layer)
.init();
set_global_propagator();
let app = Router::new()
.route("/", get(root))
.layer(opentelemetry_tracing_layer())
.route("/health", get(health));
let addr = SocketAddr::from(([0, 0, 0, 0], 3025));
tracing::info!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.with_graceful_shutdown(ddtrace::axum::shutdown_signal())
.await
.unwrap();
Ok(())
}
async fn root() -> &'static str {
do_something().await;
"Hello, World!"
}
#[tracing::instrument]
async fn do_something() {
tokio::time::sleep(Duration::from_millis(120)).await;
do_something_else().await;
tracing::info!("in the middle of doing something");
tokio::time::sleep(Duration::from_millis(10)).await;
do_something_else().await;
tokio::time::sleep(Duration::from_millis(20)).await;
}
#[tracing::instrument]
async fn do_something_else() {
tokio::time::sleep(Duration::from_millis(40)).await;
}
async fn health() -> &'static str {
"healthy"
}
请参阅完整的项目,其中包含 Cargo.toml
,请在此处查看。
Datadog 代理设置
Datadog 代理需要配置为通过 gRPC 接收 OTel 跟踪。请参考 Datadog 文档设置代理。
更多上下文和理由
导出跟踪
对于追踪,官方的Datadog代理可以处理OTel追踪数据,只需正确设置环境变量。追踪数据可以通过HTTP或gRPC发送。更多相关信息请参阅这里。
OpenTelemetry有一个官方的Rust crate,其中包含对主要格式/提供程序的扩展。这包括一个Datadog导出器。我们发现这个导出器的可靠性不如将数据发送到Datadog代理OTel端点的标准OTel导出器。这个crate是在OTel导出器的基础上构建的。
传播
两种常用的传播标准是B3
(OpenZipkin的传播风格)和Jaeger。OpenTelemetry支持这两种。
大多数Datadog SDK都支持B3
和Datadog本地的传播风格。例如,Python的ddtrace
库支持B3
,但需要显式启用。
为了方便与其他使用官方Datadog SDK编写的服务集成,我们选择了坚持使用Datadog风格的传播而不是B3
。这是通过set_global_propagator
函数设置的。
Reqwest传播
Python库会自动处理追踪上下文的传播。不幸的是,在Rust中我们需要手动处理。
可以说,HTTP请求中的传播是最常见的需求。这个crate不提供任何额外支持,但我们建议在使用reqwest
时使用reqwest-middleware crate来注入必要的头信息。如果您使用ddtrace
设置了全局传播器,它将直接生效。
use ddtrace::set_global_propagator;
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_tracing::TracingMiddleware;
#[tokio::main]
async fn main() {
set_global_propagator();
client = get_http_client();
// configure tracing, setup your app and inject the client
}
fn get_http_client() -> ClientWithMiddleware {
ClientBuilder::new(reqwest::Client::new())
.with(TracingMiddleware::default())
.build()
}
依赖关系
~15–27MB
~392K SLoC