Rust性能测量与指标收集库measured-derive的使用,提供高效的自定义度量派生宏

Rust性能测量与指标收集库measured-derive的使用,提供高效的自定义度量派生宏

安装

在项目目录中运行以下Cargo命令:

cargo add measured-derive

或者在Cargo.toml中添加以下行:

measured-derive = "0.0.23"

基本使用示例

measured-derive是一个Rust派生宏库,用于为结构体自动生成性能测量和指标收集的相关实现。下面是一个基本示例:

use measured_derive::Measured;

#[derive(Measured)]
struct MyStruct {
    #[metric(name = "my_counter", description = "A simple counter metric")]
    counter: Counter,
    
    #[metric(
        name = "response_time", 
        description = "HTTP response time histogram",
        labels = ["status_code", "method"]
    )]
    histogram: Histogram,
    
    #[metric(
        name = "cache_hits", 
        description = "Cache hit gauge",
        dynamic_labels = ["cache_name"]
    )]
    gauge: Gauge,
}

完整示例Demo

下面是一个更完整的示例,展示如何使用measured-derive进行实际性能测量:

use measured_derive::Measured;
use measured::{Counter, Histogram, Gauge};
use std::time::Instant;

#[derive(Measured)]
pub struct ApiMetrics {
    #[metric(
        name = "http_requests_total",
        description = "Total number of HTTP requests",
        labels = ["method", "status_code"]
    )]
    requests: Counter,
    
    #[metric(
        name = "http_response_time_seconds",
        description = "HTTP response time in seconds",
        labels = ["method", "status_code"]
    )]
    response_time: Histogram,
    
    #[metric(
        name = "active_connections",
        description = "Current number of active connections"
    )]
    active_connections: Gauge,
}

impl ApiMetrics {
    pub fn new() -> Self {
        Self {
            requests: Counter::default(),
            response_time: Histogram::default(),
            active_connections: Gauge::default(),
        }
    }
    
    pub fn record_request(&self, method: &str, status_code: &str, start_time: Instant) {
        // 记录请求计数
        self.requests.inc_by_labels(&[method, status_code], 1);
        
        // 记录响应时间
        let duration = start_time.elapsed();
        self.response_time
            .observe_by_labels(&[method, status_code], duration.as_secs_f64());
    }
    
    pub fn connection_opened(&self) {
        self.active_connections.inc(1);
    }
    
    pub fn connection_closed(&self) {
        self.active_connections.dec(1);
    }
}

fn main() {
    let metrics = ApiMetrics::new();
    
    // 记录一些示例数据
    let start = Instant::now();
    metrics.record_request("GET", "200", start);
    
    metrics.connection_opened();
    metrics.connection_closed();
    
    // 通常你会在这里导出指标到Prometheus或其他监控系统
    println!("Metrics recorded!");
}

特性说明

  1. 自动指标生成:通过#[derive(Measured)]自动为结构体实现指标收集功能

  2. 丰富的配置选项

    • name: 设置指标名称
    • description: 添加指标描述
    • labels: 定义静态标签
    • dynamic_labels: 定义动态标签
  3. 支持多种指标类型

    • Counter: 计数器,只能增加
    • Gauge: 仪表盘,可以增加或减少
    • Histogram: 直方图,用于测量值的分布

许可证

该项目采用MIT或Apache-2.0双重许可。


1 回复

Rust性能测量与指标收集库measured-derive使用指南

measured-derive是一个Rust宏库,用于简化性能测量和指标收集的实现。它通过派生宏自动为你的类型添加度量功能,让你可以轻松收集和报告应用程序的性能指标。

主要特性

  • 自动为结构体实现度量功能
  • 支持自定义度量指标
  • 高性能低开销的测量
  • 灵活的指标聚合方式
  • 与常见监控系统兼容

基本使用方法

1. 添加依赖

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

[dependencies]
measured-derive = "0.5"
measured = "0.5"

2. 基本示例

use measured_derive::measured;

#[measured]
fn process_data(input: &str) -> String {
    // 模拟耗时操作
    std::thread::sleep(std::time::Duration::from_millis(100));
    input.to_uppercase()
}

fn main() {
    let result = process_data("hello");
    println!("Result: {}", result);
    
    // 获取并打印度量结果
    let metrics = measured::global_collector().lock().unwrap().snapshot();
    println!("Metrics: {:?}", metrics);
}

3. 结构体度量

use measured_derive::measured;

#[measured]
struct DataProcessor {
    cache: Vec<String>,
}

impl DataProcessor {
    #[measured]
    fn process(&mut self, input: &str) -> String {
        let result = input.to_uppercase();
        self.cache.push(result.clone());
        result
    }
    
    #[measured(histogram = true)] // 使用直方图记录耗时分布
    fn batch_process(&self, inputs: &[&str]) -> Vec<String> {
        inputs.iter().map(|&s| s.to_uppercase()).collect()
    }
}

fn main() {
    let mut processor = DataProcessor { cache: Vec::new() };
    let result = processor.process("test");
    println!("Processed: {}", result);
    
    let batch = processor.batch_process(&["a", "b", "c"]);
    println!("Batch: {:?}", batch);
    
    // 获取度量数据
    let metrics = measured::global_collector().lock().unwrap().snapshot();
    println!("{:#?}", metrics);
}

高级用法

自定义指标名称

#[measured(metric = "custom.metric.name")]
fn my_function() {
    // ...
}

多维度度量

#[measured(tags = ["env:production", "region:us-west"])]
fn api_handler() {
    // ...
}

错误计数

#[measured]
fn fallible_operation() -> Result<(), String> {
    // 自动记录错误计数
    if rand::random() {
        Err("Something went wrong".into())
    } else {
        Ok(())
    }
}

指标导出

measured库支持将收集的指标导出到各种监控系统:

use measured::TextEncoder;

fn export_metrics() {
    let collector = measured::global_collector();
    let metrics = collector.lock().unwrap().snapshot();
    
    // 导出为Prometheus格式
    let mut buffer = Vec::new();
    let encoder = TextEncoder::new();
    encoder.encode(&metrics, &mut buffer).unwrap();
    
    println!("Prometheus Metrics:\n{}", String::from_utf8(buffer).unwrap());
}

配置选项

你可以在全局或单个测量点配置各种参数:

use measured::{Collector, MetricParams};

fn configure_collector() {
    let collector = Collector::new();
    collector.configure_metric(
        "my_metric",
        MetricParams::new()
            .with_histogram_enabled(true)
            .with_histogram_buckets(vec![0.1, 0.5, 1.0, 2.5, 5.0]),
    );
    
    measured::set_global_collector(collector);
}

性能考虑

measured-derive设计时考虑了性能:

  • 使用原子操作进行计数
  • 采样而不是全量记录
  • 延迟初始化昂贵的资源
  • 允许禁用特定环境下的度量

实际应用场景

  1. Web服务端点监控
  2. 批处理任务性能分析
  3. 算法性能比较
  4. 系统资源使用跟踪
  5. 业务指标收集

完整示例demo

下面是一个结合多种特性的完整示例:

use measured_derive::measured;
use measured::{Collector, MetricParams, TextEncoder};
use std::thread;
use std::time::Duration;

// 配置全局收集器
fn setup_collector() {
    let collector = Collector::new();
    collector.configure_metric(
        "api_processing_time",
        MetricParams::new()
            .with_histogram_enabled(true)
            .with_histogram_buckets(vec![0.1, 0.5, 1.0, 2.5, 5.0]),
    );
    measured::set_global_collector(collector);
}

// 带有自定义指标名称和标签的API处理器
#[measured(metric = "api_processing_time", tags = ["api:v1", "method:data"])]
fn api_data_processor(input: &str) -> Result<String, String> {
    // 模拟处理时间
    let delay_ms = match input.len() {
        0..=5 => 100,
        6..=10 => 300,
        _ => 800,
    };
    thread::sleep(Duration::from_millis(delay_ms));
    
    // 随机模拟错误
    if rand::random::<f32>() < 0.2 {
        Err("Processing failed".into())
    } else {
        Ok(input.to_uppercase())
    }
}

// 度量结构体
#[measured]
struct DataService {
    requests_processed: usize,
}

impl DataService {
    #[measured]
    fn handle_request(&mut self, input: &str) -> Result<String, String> {
        self.requests_processed += 1;
        api_data_processor(input)
    }
}

fn main() {
    // 初始化收集器
    setup_collector();
    
    // 创建服务实例
    let mut service = DataService { requests_processed: 0 };
    
    // 模拟请求处理
    let inputs = ["hello", "world", "rust", "performance", "measurement"];
    for input in inputs.iter() {
        match service.handle_request(input) {
            Ok(result) => println!("Processed: {}", result),
            Err(e) => println!("Error: {}", e),
        }
    }
    
    // 导出指标
    let collector = measured::global_collector();
    let metrics = collector.lock().unwrap().snapshot();
    
    let mut buffer = Vec::new();
    let encoder = TextEncoder::new();
    encoder.encode(&metrics, &mut buffer).unwrap();
    
    println!("\n=== Metrics ===\n{}", String::from_utf8(buffer).unwrap());
}

这个完整示例展示了:

  1. 全局收集器配置
  2. 自定义指标名称和标签
  3. 自动错误计数
  4. 结构体和方法级别的度量
  5. 指标导出功能
  6. 直方图分布记录

运行此程序将输出处理结果以及收集的指标数据,包括调用次数、耗时分布和错误计数等信息。

回到顶部