Rust OpenMetrics解析库openmetrics-parser的使用,高效解析和操作Prometheus监控指标格式

Rust OpenMetrics解析库openmetrics-parser的使用,高效解析和操作Prometheus监控指标格式

以下是内容中提供的示例代码:

use openmetrics_parser::OpenMetricsParser;
use openmetrics_parser::types::*;

fn main() {
    // 示例 OpenMetrics/Prometheus 格式数据
    let metrics_data = r#"
        # HELP http_requests_total The total number of HTTP requests.
        # TYPE http_requests_total counter
        http_requests_total{method="post",code="200"} 1027 1395066363000
        http_requests_total{method="post",code="400"}    3 1395066363000
        
        # HELP cpu_usage Current CPU usage
        # TYPE cpu_usage gauge
        cpu_usage{core="0"} 0.54
        cpu_usage{core="1"} 0.62
        
        # HELP request_duration_seconds A histogram of the request duration.
        # TYPE request_duration_seconds histogram
        request_duration_seconds_bucket{le="0.05"} 24054
        request_duration_seconds_bucket{le="0.1"} 33444
        request_duration_seconds_bucket{le="0.2"} 100392
        request_duration_seconds_bucket{le="0.5"} 129389
        request_duration_seconds_bucket{le="1"} 133988
        request_duration_seconds_bucket{le="+Inf"} 144320
        request_duration_seconds_sum 53423
        request_duration_seconds_count 144320
        
        # HELP rpc_duration_seconds A summary of the RPC duration in seconds.
        # TYPE rpc_duration_seconds summary
        rpc_duration_seconds{quantile="0.01"} 3102
        rpc_duration_seconds{quantile="0.05"} 3272
        rpc_duration_seconds{quantile="0.5"} 4773
        rpc_duration_seconds_sum 1.7560473e+07
        rpc_duration_seconds_count 2693
    "#;

    // 创建解析器实例
    let parser = OpenMetricsParser::new();
    
    // 解析指标数据
    let result = parser.parse(metrics_data);
    
    // 处理解析结果
    match result {
        Ok(metrics) => {
            println!("成功解析 {} 个指标族", metrics.len());
            
            // 遍历所有指标族
            for metric_family in metrics {
                println!("\n指标名称: {}", metric_family.name);
                println!("帮助文本: {}", metric_family.help);
                println!("类型: {:?}", metric_family.metric_type);
                
                // 遍历指标族中的所有指标
                for metric in metric_family.metrics {
                    match metric {
                        Metric::Counter(counter) => {
                            println!("计数器值: {}", counter.value);
                            for label in counter.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Gauge(gauge) => {
                            println!("测量值: {}", gauge.value);
                            for label in gauge.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Histogram(histogram) => {
                            println!("直方图总和: {}", histogram.sum);
                            println!("直方图计数: {}", histogram.count);
                            for bucket in histogram.buckets {
                                println!(" 桶(le={}): {}", bucket.upper_bound, bucket.count);
                            }
                            for label in histogram.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Summary(summary) => {
                            println!("摘要总和: {}", summary.sum);
                            println!("摘要计数: {}", summary.count);
                            for quantile in summary.quantiles {
                                println!(" 分位数({}): {}", quantile.quantile, quantile.value);
                            }
                            for label in summary.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                    }
                }
            }
        },
        Err(e) => {
            eprintln!("解析错误: {}", e);
        }
    }
}

完整示例代码

以下是一个更完整的示例,展示如何从文件中读取指标数据并处理解析结果:

use std::fs;
use openmetrics_parser::OpenMetricsParser;
use openmetrics_parser::types::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 从文件读取指标数据
    let metrics_data = fs::read_to_string("metrics.txt")?;
    
    // 创建解析器实例
    let parser = OpenMetricsParser::new();
    
    // 解析指标数据
    let result = parser.parse(&metrics_data);
    
    // 处理解析结果
    match result {
        Ok(metrics) => {
            println!("成功解析 {} 个指标族", metrics.len());
            
            // 遍历所有指标族
            for metric_family in metrics {
                println!("\n指标名称: {}", metric_family.name);
                println!("帮助文本: {}", metric_family.help);
                println!("类型: {:?}", metric_family.metric_type);
                
                // 遍历指标族中的所有指标
                for metric in metric_family.metrics {
                    match metric {
                        Metric::Counter(counter) => {
                            println!("计数器值: {}", counter.value);
                            println!("时间戳: {:?}", counter.timestamp);
                            for label in counter.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Gauge(gauge) => {
                            println!("测量值: {}", gauge.value);
                            println!("时间戳: {:?}", gauge.timestamp);
                            for label in gauge.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Histogram(histogram) => {
                            println!("直方图总和: {}", histogram.sum);
                            println!("直方图计数: {}", histogram.count);
                            println!("时间戳: {:?}", histogram.timestamp);
                            for bucket in histogram.buckets {
                                println!(" 桶(le={}): {}", bucket.upper_bound, bucket.count);
                            }
                            for label in histogram.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                        Metric::Summary(summary) => {
                            println!("摘要总和: {}", summary.sum);
                            println!("摘要计数: {}", summary.count);
                            println!("时间戳: {:?}", summary.timestamp);
                            for quantile in summary.quantiles {
                                println!(" 分位数({}): {}", quantile.quantile, quantile.value);
                            }
                            for label in summary.labels {
                                println!(" 标签: {} = {}", label.name, label.value);
                            }
                        },
                    }
                }
            }
        },
        Err(e) => {
            eprintln!("解析错误: {}", e);
        }
    }
    
    Ok(())
}

流式处理示例

对于大文件或网络流数据,可以使用流式处理方式:

use std::io::{BufRead, BufReader};
use std::fs::File;
use openmetrics_parser::OpenMetricsParser;

fn process_large_file() -> Result<(), Box<dyn std::error::Error>> {
    // 打开文件
    let file = File::open("large_metrics.txt")?;
    let reader = BufReader::new(file);
    
    // 创建解析器实例
    let mut parser = OpenMetricsParser::new();
    
    // 逐行读取并解析
    for line in reader.lines() {
        let line = line?;
        parser.parse_chunk(&line)?;
    }
    
    // 获取最终解析结果
    let metrics = parser.finalize()?;
    
    // 处理解析结果...
    println!("成功解析 {} 个指标族", metrics.len());
    
    Ok(())
}

自定义解析选项示例

use openmetrics_parser::OpenMetricsParser;

fn custom_parser() {
    // 创建自定义解析器
    let parser = OpenMetricsParser::builder()
        .allow_invalid_utf8(true)  // 允许无效UTF-8字符
        .ignore_timestamps(false)   // 不忽略时间戳
        .build();
        
    // 使用自定义解析器解析数据...
    let metrics_data = "...";
    let result = parser.parse(metrics_data);
    
    // 处理结果...
}

以上示例展示了openmetrics-parser库的基本用法和高级功能,包括文件读取、流式处理和自定义解析选项。


1 回复

Rust OpenMetrics解析库openmetrics-parser使用指南

概述

openmetrics-parser是一个用于解析OpenMetrics/Prometheus监控指标格式的Rust库。它提供了高效解析和操作Prometheus监控指标的能力,支持OpenMetrics文本格式的完整解析。

主要特性

  • 完全兼容OpenMetrics文本格式
  • 零拷贝解析
  • 支持所有Prometheus指标类型
  • 提供便捷的指标访问接口
  • 良好的错误处理

安装

在Cargo.toml中添加依赖:

[dependencies]
openmetrics-parser = "0.5"

基本使用方法

解析OpenMetrics文本

use openmetrics_parser::OpenMetricsParser;

let text = r#"
# TYPE http_requests_total counter
# HELP http_requests_total The total number of HTTP requests.
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"}    3 1395066363000
"#;

let parser = OpenMetricsParser::new();
let result = parser.parse(text).unwrap();

println!("解析到的指标数量: {}", result.metrics().count());

访问解析后的指标

for metric in result.metrics() {
    println!("指标名称: {}", metric.name());
    println!("指标类型: {:?}", metric.metric_type());
    println!("帮助文本: {:?}", metric.help());
    
    for sample in metric.samples() {
        println!("  样本值: {}", sample.value());
        println!("  时间戳: {:?}", sample.timestamp());
        
        for (label, value) in sample.labels() {
            println!("    标签: {} = {}", label, value);
        }
    }
}

创建自定义指标

use openmetrics_parser::model::{Metric, MetricType, Sample};

let mut metric = Metric::new("custom_metric", MetricType::Gauge);
metric.add_sample(Sample::new(42.0).with_label("env", "production"));

let parser = OpenMetricsParser::new();
let text = parser.serialize_metric(&metric);

println!("生成的OpenMetrics文本:\n{}", text);

高级用法

处理大文件

对于大文件,可以使用流式解析:

use std::fs::File;
use std::io::BufReader;
use openmetrics_parser::OpenMetricsParser;

let file = File::open("metrics.txt").unwrap();
let reader = BufReader::new(file);

let parser = OpenMetricsParser::new();
let result = parser.parse_from_reader(reader).unwrap();

// 处理结果...

错误处理

let invalid_text = "invalid metric format";
match parser.parse(invalid_text) {
    Ok(result) => {
        // 处理成功结果
    },
    Err(e) => {
        eprintln!("解析错误: {}", e);
        // 处理错误
    }
}

性能提示

  1. 对于重复解析,重用OpenMetricsParser实例
  2. 大文件使用parse_from_reader而不是parse
  3. 不需要时间戳时可以忽略它们以提高性能

完整示例:构建监控指标处理器

use openmetrics_parser::model::{Metric, MetricType, Sample};
use openmetrics_parser::OpenMetricsParser;
use std::collections::HashMap;

// 自定义指标处理器结构体
struct MetricProcessor {
    parser: OpenMetricsParser,
    metrics: HashMap<String, Metric>,
}

impl MetricProcessor {
    // 创建新的处理器实例
    pub fn new() -> Self {
        Self {
            parser: OpenMetricsParser::new(),
            metrics: HashMap::new(),
        }
    }
    
    // 解析OpenMetrics文本并存储指标
    pub fn parse_and_store(&mut self, text: &str) -> Result<(), String> {
        let result = self.parser.parse(text).map_err(|e| e.to_string())?;
        
        for metric in result.metrics() {
            let name = metric.name().to_string();
            let mut new_metric = Metric::new(&name, metric.metric_type());
            
            if let Some(help) = metric.help() {
                new_metric.set_help(help);
            }
            
            for sample in metric.samples() {
                let mut new_sample = Sample::new(sample.value());
                
                for (label, value) in sample.labels() {
                    new_sample = new_sample.with_label(label, value);
                }
                
                if let Some(timestamp) = sample.timestamp() {
                    new_sample = new_sample.with_timestamp(timestamp);
                }
                
                new_metric.add_sample(new_sample);
            }
            
            self.metrics.insert(name, new_metric);
        }
        
        Ok(())
    }
    
    // 获取所有指标
    pub fn get_metrics(&self) -> Vec<&Metric> {
        self.metrics.values().collect()
    }
    
    // 获取特定指标
    pub fn get_metric(&self, name: &str) -> Option<&Metric> {
        self.metrics.get(name)
    }
    
    // 导出为OpenMetrics格式文本
    pub fn export(&self) -> String {
        let mut output = String::new();
        
        for metric in self.metrics.values() {
            output.push_str(&self.parser.serialize_metric(metric));
            output.push('\n');
        }
        
        output
    }
}

fn main() {
    let mut processor = MetricProcessor::new();
    
    // 示例OpenMetrics文本
    let text = r#"
# TYPE cpu_usage gauge
# HELP cpu_usage Current CPU usage percentage
cpu_usage{core="0"} 25.3
cpu_usage{core="1"} 32.1

# TYPE memory_bytes gauge
# HELP memory_bytes Memory usage in bytes
memory_bytes{type="free"} 1024000
memory_bytes{type="used"} 2048000
"#;
    
    // 解析并存储指标
    match processor.parse_and_store(text) {
        Ok(_) => {
            println!("成功解析并存储指标");
            
            // 获取并打印特定指标
            if let Some(cpu_metric) = processor.get_metric("cpu_usage") {
                println!("CPU指标:");
                for sample in cpu_metric.samples() {
                    println!("  {}: {}", sample.labels().next().unwrap().1, sample.value());
                }
            }
            
            // 导出所有指标
            println!("\n导出的OpenMetrics格式:");
            println!("{}", processor.export());
        },
        Err(e) => {
            eprintln!("解析错误: {}", e);
        }
    }
}

这个库非常适合需要处理Prometheus/OpenMetrics格式数据的Rust应用程序,特别是在构建监控工具、指标代理或自定义导出器时。

回到顶部