开始使用
本页面将向您展示如何在 Rust 中开始使用 OpenTelemetry。
您将学习如何为一个简单的 Rust 应用程序进行仪表化,以便将 [跟踪][] 发送到控制台。
先决条件
确保已在本地安装了以下内容:
示例应用程序
以下示例使用一个基本的 hyper 应用程序。如果您不使用 hyper,没问题 —— 您也可以使用 OpenTelemetry Rust 与其他 HTTP 实现,如 Actix Web 和 Tide。有关受支持的框架的完整列表,请参阅 registry。
有关更多详细示例,请参阅 examples。
依赖项
首先,在一个新的目录中创建一个名为 Cargo.toml
的文件,并添加以下内容:
[package]
name = "dice_server"
version = "0.1.0"
edition = "2021"
publish = false
[[bin]]
name = "dice_server"
path = "dice_server.rs"
doc = false
[dependencies]
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1.29", features = ["full"] }
rand = { version = "0.8" }
创建和启动 HTTP 服务器
在同一文件夹中,创建一个名为 dice_server.rs
的文件,并将以下代码添加到文件中:
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server, Method, StatusCode};
use rand::Rng;
use std::{convert::Infallible, net::SocketAddr};
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let mut response = Response::new(Body::empty());
match (req.method(), req.uri().path()) {
(&Method::GET, "/rolldice") => {
let random_number = rand::thread_rng().gen_range(1..7);
*response.body_mut() = Body::from(random_number.to_string());
}
_ => {
*response.status_mut() = StatusCode::NOT_FOUND;
}
};
Ok(response)
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
let server = Server::bind(&addr).serve(make_svc);
println!("Listening on {addr}");
if let Err(e) = server.await {
eprintln!("server error: {e}");
}
}
使用以下命令构建并运行应用程序,然后在您的网页浏览器中打开 http://localhost:8080/rolldice,以确保它正常工作。
$ cargo run --bin dice_server
...
Listening on 127.0.0.1:8080
仪表化
要将 OpenTelemetry 添加到您的应用程序中,请使用以下附加依赖项更新 Cargo.toml
:
opentelemetry = { version = "0.20", features = ["trace"] }
opentelemetry-stdout = { version = "0.1", features = ["trace"] }
将 dice_server.rs
文件更新为以下代码,以初始化跟踪器并在调用 handle
函数时发出跟踪:
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use rand::Rng;
use std::{convert::Infallible, net::SocketAddr};
use opentelemetry::global::ObjectSafeSpan;
use opentelemetry::trace::{SpanKind, Status};
use opentelemetry::sdk::trace::TracerProvider;
use opentelemetry::{global, sdk::propagation::TraceContextPropagator, trace::Tracer};
use opentelemetry_stdout::SpanExporter;
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let mut response = Response::new(Body::empty());
let tracer = global::tracer("dice_server");
let mut span = tracer
.span_builder(format!("{} {}", req.method(), req.uri().path()))
.with_kind(SpanKind::Server)
.start(&tracer);
match (req.method(), req.uri().path()) {
(&Method::GET, "/rolldice") => {
let random_number = rand::thread_rng().gen_range(1..7);
*response.body_mut() = Body::from(random_number.to_string());
span.set_status(Status::Ok);
}
_ => {
*response.status_mut() = StatusCode::NOT_FOUND;
span.set_status(Status::error("Not Found"));
}
};
Ok(response)
}
fn init_tracer() {
global::set_text_map_propagator(TraceContextPropagator::new());
let provider = TracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider);
}
#[tokio::main]
async fn main() {
init_tracer();
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
let server =
Server::bind(&addr).serve(make_svc);
println!("Listening on {addr}");
if let Err(e) = server.await {
eprintln!("server error: {e}");
}
}
再次启动服务器:
$ cargo run --bin dice_server
...
Listening on 127.0.0.1:8080
当您向服务器发送请求 http://localhost:8080/rolldice 时,您将在控制台上看到一个跟踪(输出进行了漂亮的打印以方便查看):
{
"resourceSpans": [
{
"resource": {
"attributes": [
{
"key": "service.name",
"value": {
"stringValue": "unknown_service"
}
}
]
},
"scopeSpans": [
{
"scope": {
"name": "dice_server"
},
"spans": [
{
"attributes": [],
"droppedAttributesCount": 0,
"droppedEventsCount": 0,
"droppedLinksCount": 0,
"endTimeUnixNano": 1691076354768034000,
"kind": 2,
"name": "GET /rolldice",
"parentSpanId": "",
"spanId": "27e1d7d8e44a63c5",
"startTimeUnixNano": 1691076354768025000,
"status": {
"code": 2
},
"traceId": "adfe9d364ee19610adde517d722167ca"
}
]
}
]
}
]
}
下一步是什么?
了解更多:
最后修改 December 10, 2023: translate (a4350d6e)