Rust应用监控:从A到Z的指标与告警

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust应用监控:从A到Z的指标与告警



当您的Rust应用进入生产环境后,代码就不再仅仅是代码。它变成了一个服务,用户和业务都依赖于它。没有监控,您就像在盲目飞行:故障通过投诉被发现,性能则靠“目测”评估。在本文中,我们将探讨如何为Rust构建一个完整的监控系统——从基本指标收集到Prometheus告警配置和Grafana可视化。



1. 为什么监控对Rust项目很重要

Rust以高性能和内存安全性著称,但这并不意味着不需要关注应用。生产环境中的典型问题包括:

  • 内存泄漏(例如通过Arc或循环引用)。
  • 异步代码中的阻塞(tokio中的死锁或饥饿)。
  • 意外恐慌(即使使用了catch_unwind)。
  • 性能下降由于次优算法。

监控回答了以下问题:“现在发生了什么?”、“为什么会发生?”以及“如何预防?”



2. 指标收集:metrics库与导出到Prometheus

Rust的标准技术栈是metricscrate(或prometheus)。我们使用metrics,因为它抽象了导出过程,并且可以轻松更换后端。



2.1. 安装与基本配置

在Cargo.toml中添加依赖:

[dependencies]metrics = "0.21"metrics-exporter-prometheus = "0.12"tokio = { version = "1", features = ["full"] }


为/metrics端点创建一个简单的HTTP服务器:

use metrics_exporter_prometheus::PrometheusBuilder;use std::net::SocketAddr;use tokio::net::TcpListener;

#[tokio::main]async fn main() { // 初始化Prometheus导出器 let (recorder, exporter) = PrometheusBuilder::new() .build() .expect("无法创建Prometheus导出器");

metrics::set_boxed_recorder(Box::new(recorder)) .expect("无法设置全局记录器");

// 启动指标服务器 let addr: SocketAddr = "0.0.0.0:9090".parse().unwrap(); let listener = TcpListener::bind(addr).await.unwrap(); println!("指标可在 http://{} 获取", addr);

loop { let (mut stream, _) = listener.accept().await.unwrap(); let body = exporter.encode().unwrap(); let response = format!( "HTTP/1.1 200 OK\\rContent-Type: text/plain\\rContent-Length: {}\\r\\r{}", body.len(), body ); tokio::io::AsyncWriteExt::write_all(&mut stream, response.as_bytes()) .await .unwrap(); }}


2.2. 注册自定义指标

添加请求计数器和响应时间直方图:

use metrics::{counter, histogram, increment_counter};use std::time::Instant;

async fn handle_request() { let start = Instant::now();

// 您的业务逻辑 tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;

// 记录指标 increment_counter!("http_requests_total", "method" => "GET"); histogram!("http_request_duration_seconds", start.elapsed().as_secs_f64(), "method" => "GET");}

现在在/metrics端点您将看到:

# HELP http_requests_total Total HTTP requests# TYPE http_requests_total counterhttp_requests_total{method="GET"} 1# HELP http_request_duration_seconds HTTP request duration# TYPE http_request_duration_seconds histogramhttp_request_duration_seconds_bucket{method="GET",le="0.005"} 0http_request_duration_seconds_bucket{method="GET",le="0.01"} 0http_request_duration_seconds_bucket{method="GET",le="0.025"} 0                

博客

书籍推荐