Rust Web框架Rocket的Prometheus监控插件rocket_prometheus使用指南,实现高性能应用指标采集与可视化

Rocket Prometheus监控插件使用指南

基本用法

首先在Cargo.toml中添加依赖:

[dependencies]
rocket = "0.5.0"
rocket_prometheus = "0.10.1"

然后在Rocket应用中添加并挂载PrometheusMetrics实例:

use rocket_prometheus::PrometheusMetrics;

#[rocket::launch]
fn launch() -> _ {
    let prometheus = PrometheusMetrics::new();
    rocket::build()
        .attach(prometheus.clone())
        .mount("/metrics", prometheus)
}

这样会在应用的/metrics端点暴露如下指标:

$ curl localhost:8000/metrics
# HELP rocket_http_requests_duration_seconds HTTP request duration in seconds for all requests
# TYPE rocket_http_requests_duration_seconds histogram
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.005"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.01"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.025"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.05"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.1"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/ metrics",method="GET",status="200",le="0.25"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="0.5"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="1"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="2.5"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="5"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="10"} 2
rocket_http_requests_duration_seconds_bucket{endpoint="/metrics",method="GET",status="200",le="+Inf"} 2
rocket_http_requests_duration_seconds_sum{endpoint="/metrics",method="GET",status="200"} 0.0011045669999999999
rocket_http_requests_duration_seconds_count{endpoint="/metrics",method="GET",status="200"} 2
# HELP rocket_http_requests_total Total number of HTTP requests
# TYPE rocket_http_requests_total counter
rocket_http_requests_total{endpoint="/metrics",method="GET",status="200"} 2

默认指标

该插件默认跟踪两个指标:

  • rocket_http_requests_total (标签: endpoint, method, status): Rocket处理的HTTP请求总数
  • rocket_http_requests_duration_seconds (标签: endpoint, method, status): Rocket处理的所有HTTP请求的请求持续时间

可以通过设置ROCKET_PROMETHEUS_NAMESPACE环境变量来更改这些指标的"rocket"前缀。

自定义指标

可以通过向PrometheusMetrics实例的注册表注册新指标来跟踪更多指标:

#[macro_use]
use once_cell::sync::Lazy;
use rocket::{get, launch, routes};
use rocket_prometheus::{
    prometheus::{opts, IntCounterVec},
    PrometheusMetrics,
};

static NAME_COUNTER: Lazy<IntCounterVec> = Lazy::new(|| {
    IntCounterVec::new(opts!("name_counter", "Count of names"), &["name"])
        .expect("Could not create NAME_COUNTER")
});

#[get("/hello/<name>")]
pub fn hello(name: &str) -> String {
    NAME_COUNTER.with_label_values(&[name]).inc();
    format!("Hello, {}!", name)
}

#[launch]
fn launch() -> _ {
    let prometheus = PrometheusMetrics::new();
    prometheus
        .registry()
        .register(Box::new(NAME_COUNTER.clone()))
        .unwrap();
    rocket::build()
        .attach(prometheus.clone())
        .mount("/", routes![hello])
        .mount("/metrics", prometheus)
}

完整示例代码

use once_cell::sync::Lazy;
use rocket::{get, launch, routes};
use rocket_p极地us::{
    prometheus::{opts, IntCounterVec, HistogramOpts, Histogram},
    PrometheusMetrics,
};

// 定义自定义计数器
static NAME_COUNTER: Lazy<IntCounterVec> = Lazy::new(|| {
    IntCounterVec::new(opts!("name_counter", "Count of names"), &["name"])
        .expect("Could not create NAME_COUNTER")
});

// 定义自定义直方图
static RESPONSE_TIME: Lazy<Histogram> = Lazy::new(|| {
    Histogram::with_opts(HistogramOpts::new(
        "response_time_seconds",
        "Response time in seconds",
    ))
    .expect("Could not create RESPONSE_TIME")
});

#[get("/hello/<name>")]
pub fn hello(name: &str) -> String {
    // 记录名称访问次数
    NAME_COUNTER.with_label_values(&[name]).inc();
    
    // 计时器开始
    let timer = RESPONSE_TIME.start_timer();
    
    // 模拟处理时间
    std::thread::sleep(std::time::Duration::from_millis(100));
    
    // 计时器结束并记录
    timer.observe_duration();
    
    format!("Hello, {}!", name)
}

#[launch]
fn launch() -> _ {
    let prometheus = PrometheusMetrics::new();
    
    // 注册自定义指标
    prometheus
        .registry()
        .register(Box::new(NAME_COUNTER.clone()))
        .unwrap();
    prometheus
        .registry()
        .register(Box::new(RESPONSE_TIME.clone()))
        .unwrap();
        
    rocket::build()
        .attach(prometheus.clone())
        .mount("/", routes![hello])
        .mount("/metrics", prometheus)
}

这个完整示例展示了如何:

  1. 创建一个基本的Rocket应用
  2. 集成Prometheus监控
  3. 添加自定义计数器指标(NAME_COUNTER)
  4. 添加自定义直方图指标(RESPONSE_TIME)
  5. 在路由处理程序中记录指标数据

应用启动后,访问/metrics端点可以看到所有默认和自定义的指标数据。


1 回复

以下是基于提供内容整理的完整示例demo:

基本使用方法示例

#[macro_use] extern crate rocket;

use rocket_prometheus::PrometheusMetrics;

#[launch]
fn rocket() -> _ {
    let prometheus = PrometheusMetrics::new();
    rocket::build()
        .attach(prometheus.clone())
        .mount("/metrics", prometheus)
        .mount("/", routes![index])
}

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

完整示例demo

#[macro_use] extern crate rocket;

use rocket_prometheus::{
    PrometheusMetrics,
    prometheus::{IntCounter, Histogram, opts, HistogramOpts}
};

#[launch]
fn rocket() -> _ {
    // 初始化Prometheus监控
    let prometheus = PrometheusMetrics::new()
        .with_ignore("/healthz");  // 忽略健康检查路由

    rocket::build()
        .attach(prometheus.clone())  // 附加监控中间件
        .mount("/metrics", prometheus)  // 暴露指标端点
        .mount("/", routes![
            index,
            custom_route,
            timed_route,
            healthz
        ])
}

// 基础路由
#[get("/")]
fn index() -> &'static str {
    "Welcome to Rocket with Prometheus monitoring!"
}

// 自定义计数器指标路由
#[get("/custom")]
fn custom_route() -> &'static str {
    // 创建或获取计数器
    let counter = IntCounter::with_opts(opts!(
        "custom_counter_total",
        "Total number of custom route accesses"
    )).unwrap();
    
    counter.inc();  // 递增计数器
    
    "Custom route accessed - counter incremented"
}

// 自定义直方图指标路由
#[get("/timed")]
fn timed_route() -> &'static str {
    let histogram_opts = HistogramOpts::new(
        "request_duration_seconds",
        "Time taken to process timed route"
    ).buckets(vec![0.01, 0.05, 0.1, 0.5, 1.0, 2.0]);
    
    let histogram = Histogram::with_opts(histogram_opts).unwrap();
    
    let timer = histogram.start_timer();
    // 模拟业务处理耗时
    std::thread::sleep(std::time::Duration::from_millis(rand::random::<u64>() % 200));
    timer.observe_duration();
    
    "Timed route completed - duration recorded"
}

// 健康检查路由(被忽略监控)
#[get("/healthz")]
fn healthz() -> &'static str {
    "OK"
}

Prometheus配置示例

scrape_configs:
  - job_name: 'rocket_app'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:8000']
    metrics_path: '/metrics'

使用说明

  1. 将上述代码保存为main.rs
  2. 添加依赖到Cargo.toml
[dependencies]
rocket = "0.5.0"
rocket_prometheus = "0.10.0"
rand = "0.8"
  1. 运行应用:cargo run
  2. 访问不同端点测试监控:
    • / - 基础路由(自动监控)
    • /custom - 测试计数器
    • /timed - 测试直方图
    • /healthz - 健康检查(被忽略)
  3. 查看指标:curl http://localhost:8000/metrics

这个完整示例展示了:

  • 基本监控设置
  • 自定义计数器指标
  • 自定义直方图指标(带特定桶配置)
  • 路由过滤功能
  • 完整的项目结构
  • 配套的Prometheus配置

所有代码都包含注释说明关键部分,可以直接用于实际项目。

回到顶部