- 可观测性
- 后端
【免费下载链接】highlight
highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.
本文面向在 Rust 服务端接入 highlight.io 的开发者,系统讲解两条官方支持路径:基于 actix-web 框架的中间件式接入,以及不使用框架的裸 SDK 接入。读完本文你将掌握highlightio-actix与highlightio两个 crate 的依赖配置、运行时 feature 选择、Highlight::init初始化、错误捕获、log与tracing两大生态的日志与链路数据上报,以及如何在前端会话、后端日志、分布式追踪三大面板中完成验证。
一、Rust 接入概览:两条路径怎么选
在 highlight.io 仓库中,Rust 服务端接入的官方文档入口位于 docs-content/getting-started/4_server/5_rust/1_overview.md,该页面明确给出两个接入方向:
- actix-web:在 actix-web 应用中以中间件(middleware)方式接入,自动采集每个 HTTP 请求的链路数据,对应文档 actix.md;
- Other(无框架):在任意 Rust 程序中直接使用基础 SDK,手动完成初始化、错误捕获、日志与追踪,对应文档 other.md。
两者的底层是同一套 SDK:highlightio提供核心能力(初始化、错误上报、日志后端、tracing 桥接),highlightio-actix在其之上封装了 actix-web 中间件HighlightActix。从仓库源码 sdk/highlight-rust 的目录结构可以清楚看到这一分层:highlightio是纯基础 crate,highlightio-actix依赖它并通过pub mod highlight { pub use highlightio::*; }重导出(见 highlightio-actix/src/lib.rs)。
选择建议:如果服务是基于 actix-web 构建的 HTTP 应用,直接走第一条路径,让中间件替你完成请求级链路采集;如果是后台任务、批处理或自定义网络服务,则走第二条路径,手动控制采集时机。
二、actix-web 路径:中间件式全自动接入
1. 添加依赖
在Cargo.toml中加入官方 actix 集成 crate:
[dependencies] highlightio-actix = "1"这一步来自官方快速开始内容(见 highlight.io/components/QuickstartContent/server/rust/actix.tsx),highlightio-actix会在内部拉取highlightio基础 SDK,因此只需声明这一个依赖。
2. 初始化 SDK 并挂载中间件
highlightio_actix::highlight::Highlight::init负责初始化 SDK,随后把HighlightActix作为 actix-web 中间件挂载到App上,即可开始自动追踪:
use actix_web::{App, Error, HttpServer}; use highlightio_actix::{highlight::{Highlight, HighlightConfig}, HighlightActix}; // ...your services... #[actix_web::main] async fn main() -> Result<(), Error> { let h = Highlight::init(HighlightConfig { project_id: "<YOUR_PROJECT_ID>".to_string(), service_name: "my-rust-app".to_string(), service_version: "git-sha".to_string(), ..Default::default() }).expect("Failed to initialize Highlight.io"); let _h = h.clone(); HttpServer::new(move || { App::new() .wrap(HighlightActix::new(&_h)) // ... }) .bind("127.0.0.1:8080")? .run() .await?; h.shutdown(); Ok(()) }三个关键配置项说明:
| 配置项 | 作用 | 说明 |
|---|---|---|
project_id | 项目唯一标识 | 在 highlight.io 控制台创建项目后获得,必填项;源码 lib.rs 中会校验其非空,为空直接返回HighlightError::Config错误 |
service_name | 服务名称 | 可选,对应 OpenTelemetry 语义约定的service.name资源属性,用于在面板中区分不同服务 |
service_version | 服务版本 | 可选,官方建议填最近一次部署的 git SHA,对应service.version资源属性,便于按版本排查回归 |
关于shutdown():初始化返回的Highlight句柄需要在程序退出前调用h.shutdown(),它会关闭 logger 与 tracer provider 并冲刷尚未发送的日志与链路数据。源码注释明确指出(lib.rs):如果不调用该方法,程序退出前一刻产生的日志和链路将无法送达 highlight.io。因此无论是 actix-web 还是无框架路径,都不要漏掉这行。
3. 验证错误上报
在任意 service 中抛出一个错误,然后访问 highlight 错误页面 检查后端错误是否入库:
// ... #[get("/error")] async fn error() -> Result<impl Responder, std::io::Error> { Err(std::io::Error::new( std::io::ErrorKind::Other, "Test error" ))?; Ok(format!("You shouldn't be able to see this.")) } // ... #[actix_web::main] async fn main() -> Result<(), Error> { // ... HttpServer::new(move || { App::new() .wrap(HighlightActix::new(&h)) .service(error) // add this }) // ... }从源码实现看,HighlightActix中间件会对每个请求创建SpanKind::Server的 span,并在响应出现 5xx 或中间件调用返回错误时调用span.record_error(&e)并把 span 状态置为 error(见 highlightio-actix/src/lib.rs),这就是错误自动捕获的底层机制。
4. 接入logcrate 输出日志
Highlight 与 Rust 生态的事实标准logcrate 深度集成,Highlight::init会自动安装一个日志后端(它本身实现了log::Logtrait),因此你只需引入log依赖,即可像平时一样调用宏:
[dependencies] log = "0.4"use log::{trace, debug, info, warn, error}; // ... #[get("/")] async fn index() -> impl Responder { info!("Hello, world! Greet endpoint called."); format!("Hello, world!") }这里有一个官方文档特别标注的注意事项:env_logger默认只把错误级别输出到控制台,所以想看到日志,需要设置RUST_LOG=<crate name>环境变量(或RUST_LOG=trace查看全部级别)。SDK 的默认 logger 正是env_logger::Logger::from_default_env()(见 lib.rs),它从RUST_LOG环境变量读取过滤规则,Highlight::init内部会调用log::set_boxed_logger将其注册为全局 logger,并把最大日志级别设为Trace。
5. 接入tracingcrate 记录链路
tracing是 tokio 生态的链路追踪库,highlight.io SDK 通过opentelemetry-appender-tracing的OpenTelemetryTracingBridge把 tracing 层桥接到 OTel logger(见 lib.rs)。添加依赖并创建 span / 事件:
[dependencies] tracing = "0.1"use tracing::{event, span, Level}; // ... let span = span!(Level::INFO, "my_span"); let _guard = span.enter(); event!(Level::DEBUG, "something happened inside my_span");6. 验证后端链路
访问 highlight traces 面板)。
三、无框架路径:裸 SDK 手动接入
如果你的 Rust 程序不使用 actix-web(例如 tokio 异步任务、同步 CLI、自定义网络服务),使用基础 cratehighlightio。
1. 按运行时选择 feature
highlightio的运行时特性(runtime features)是整个接入流程中最关键的决策点,官方文档要求根据项目运行环境选择:
[dependencies.highlightio] version = "1" default-features = ... features = [...]可选的 feature 及适用场景(依据 sdk/highlight-rust/highlightio/Cargo.toml):
| feature | 适用场景 | 底层实现 |
|---|---|---|
sync(默认) | 全同步代码 | opentelemetry-otlp/reqwest-blocking-client,日志与链路用install_simple同步导出 |
tokio | 基于 tokio 的异步运行时 | opentelemetry_sdk/rt-tokio+reqwest-client,批量导出 |
tokio-current-thread | 单线程 tokio 运行时 | opentelemetry_sdk/rt-tokio-current-thread |
async-std | 基于 async-std 的运行时 | opentelemetry_sdk/rt-async-std+surf-client |
规则是:
- 如果项目是纯同步代码,使用默认 feature(不写
default-features = false); - 使用
tokio时关闭默认特性并启用tokio; - 使用
async-std时关闭默认特性并启用async-std。
之所以必须显式选择,是因为 SDK 在编译期就做了硬约束:源码顶部有一段compile_error!宏(lib.rs),当四个运行时 feature 一个都没启用时会直接编译失败并提示“请指定 sync(默认)、tokio 或 async-std 之一”。反过来,如果同时启用了多个运行时,源码中的#[cfg]条件编译(lib.rs)会按优先级挑选唯一可用的导出方式,因此请务必只启用与运行时匹配的那一个。
2. 初始化 SDK
use highlightio::{Highlight, HighlightConfig}; // or async fn main() // with #[tokio::main] if you're using tokio, etc. fn main() { let h = Highlight::init(HighlightConfig { project_id: "<YOUR_PROJECT_ID>".to_string(), service_name: "my-rust-app".to_string(), service_version: "git-sha".to_string(), ..Default::default() }).expect("Failed to initialize Highlight.io"); // ... h.shutdown(); }3. 手动捕获错误
与 actix-web 的自动捕获不同,无框架路径使用Highlight::capture_error显式上报任何实现了std::error::Errortrait 的错误:
fn do_something() -> Result<(), Error> { // ... } fn main() { // ... match do_something() { Ok(_) => {}, Err(e) => h.capture_error(&e), }; }底层实现是:capture_error最终调用capture_error_with_session(err, None, None),在名为highlight-ctx的 span 内记录错误并附加highlight.session_id/highlight.trace_id属性、把 span 状态置为 error(见 lib.rs)。这也意味着如果需要把后端错误关联到具体前端会话,可以改用capture_error_with_session并传入session_id与request_id。
验证方式同样简单,在main里主动发一个测试错误:
fn main() { // ... let e = std::io::Error::new( std::io::ErrorKind::Other, "This is a test error." ); h.capture_error(&e); }随后访问 highlight 错误页面 确认后端错误入库。
4. 日志与追踪
无框架路径的日志与追踪步骤和 actix-web 路径完全一致:添加log = "0.4"与tracing = "0.1"依赖,直接调用宏即可(Highlight::init已自动安装日志后端并桥接 tracing 层):
use log::{trace, debug, info, warn, error}; // ... trace!("This is a trace! log. {:?}", "hi!"); debug!("This is a debug! log. {}", 3 * 3); info!("This is an info! log. {}", 2 + 2); warn!("This is a warn! log."); error!("This is an error! log.");use tracing::{event, span, Level}; // ... let span = span!(Level::INFO, "my_span"); let _guard = span.enter(); event!(Level::DEBUG, "something happened inside my_span");注意:官方文档同样提醒,默认 logger 是 env_logger,需要设置RUST_LOG=<crate name>(或RUST_LOG=trace)才能在控制台看到输出。
四、源码级原理:SDK 内部是如何工作的
1. 基于 OpenTelemetry 的 OTLP 导出
highlightio并不是自研协议,而是完整构建在 OpenTelemetry 生态之上。从 lib.rs 可以看到,初始化时它会同时建立两条 OTLP/HTTP 管线:
- 日志管线:
new_pipeline().logging().http(),导出端点https://otel.highlight.io:4318; - 链路管线:
new_pipeline().tracing().http(),采样器为Sampler::AlwaysOn(全量采样),批量导出配置为调度延迟 1000ms、单批最大 128 条、队列上限 1024 条,同样导出到https://otel.highlight.io:4318。
两条管线都会挂上同一个Resource,其中highlight.project_id是必须写入的资源属性,service.name/service.version仅在配置了对应字段时写入(见 lib.rs)。这也是面板端能把数据归属到正确项目的关键。
2. actix-web 中间件的自动埋点逻辑
HighlightActix实现了 actix-web 的Transform/Service中间件协议,其核心逻辑在 highlightio-actix/src/lib.rs:
- 从请求头中提取父级上下文:通过
TraceContextPropagator解析传入的 W3C trace 头,实现跨服务链路关联; - 为每个请求创建路由级别的 span:span 名取自
req.match_pattern()(即注册路由模式),kind 为SpanKind::Server; - 采集丰富的 HTTP 语义属性:HTTP 路由、客户端地址(含代理场景下的真实 IP 与 socket 地址)、服务地址端口、URL 路径与查询串、URL scheme、请求方法、HTTP 协议版本、请求体大小、User-Agent(见 req_to_attrs);
- 读取
x-highlight-request请求头(格式为session_id/trace_id),把前端会话与后端请求关联起来,写入highlight.session_id与highlight.trace_id属性——这正是前后端联动排查的桥梁; - 响应完成后写入
http.response.status_code;5xx 响应或调用链出错时记录错误并把 span 状态置为 error。
3.HighlightConfig的完整字段
除文档中演示的project_id/service_name/service_version外,HighlightConfig还暴露了第四个字段logger: Box<dyn Log>(见 lib.rs)。默认实现使用env_logger::Logger::from_default_env(),如果你希望把控制台输出交给自己的 logger(例如与项目已有的日志框架统一),可以传入自定义 logger——官方注释强调:传入的自定义 logger 不要自行注册为全局 logger,因为 SDK 会负责全局注册。SDK 自身实现log::Log的方式是:把每条log记录同时转发给 OTel 日志管线(映射为Severity级别与时间戳)和你的本地 logger(见 lib.rs),实现“远端上报 + 本地输出”双通道。
4. 示例程序
仓库 sdk/highlight-rust 中提供了三个可直接参考的示例:
highlightio-actix/examples/hello-world:actix-web 完整接入示例;highlightio/examples/sync:纯同步程序示例;highlightio/examples/tokio:tokio 异步程序示例。
五、相关文件索引
- 官方文档入口:docs-content/getting-started/4_server/5_rust/1_overview.md
- actix-web 快速开始:docs-content/getting-started/4_server/5_rust/actix.md
- 无框架快速开始:docs-content/getting-started/4_server/5_rust/other.md
- 快速开始内容定义(actix):highlight.io/components/QuickstartContent/server/rust/actix.tsx
- 快速开始内容定义(other):highlight.io/components/QuickstartContent/server/rust/other.tsx
- 核心 SDK 源码:sdk/highlight-rust/highlightio/src/lib.rs
- SDK 特性配置:sdk/highlight-rust/highlightio/Cargo.toml
- actix 中间件源码:sdk/highlight-rust/highlightio-actix/src/lib.rs
六、小结
Rust 服务端接入 highlight.io 的关键点可以浓缩为四句话:按运行时选对 feature(同步 / tokio / async-std),初始化时填对project_id并保留句柄,退出前务必调用shutdown(),actix-web 走中间件自动采集、其余场景走capture_error手动上报。SDK 底层基于 OpenTelemetry 标准通过 OTLP/HTTP 上报到https://otel.highlight.io:4318,因此在错误、日志、追踪三个面板看到的数据,本质上都是标准的 OTel 资源与语义属性,这让你既能无痛接入 highlight.io,也能与既有 OTel 观测体系互相印证。
- 可观测性
- 后端
【免费下载链接】highlight
highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.
相关推荐
highlight.io Express.js 服务端监控实战:用 Node.js SDK 接入错误、日志与 Traces
highlight.io Express.js 服务端监控实战:用 Node.js SDK 接入错误、日志与 Traces 本文基于 highlight.io
可观测性后端Highlight 上手指南:从前端到后端的全栈监控接入路径(highlight.io)
Highlight 上手指南:从前端到后端的全栈监控接入路径(highlight.io) 本篇以 highlight.io 官方文档《Getting Start
可观测性后端如何用 @react-doctor/fuzz 对单条规则做对抗性模糊测试?
如何用 @react doctor/fuzz 对单条规则做对抗性模糊测试? @react doctor/fuzz 是 react doctor 仓库内的对抗性模
可观测性后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考