#prometheus-metrics #static #definition #utilities #label #macro #build

prometheus-static-metric

为 rust-prometheus 提供静态度量辅助工具

8 个不稳定版本 (3 个破坏性更新)

使用旧版Rust 2015

0.5.1 2021年1月8日
0.5.0 2020年12月14日
0.4.0 2020年8月17日
0.2.0 2019年8月21日
0.1.4 2018年6月20日

#245 in 过程宏

Download history 2675/week @ 2024-03-14 2393/week @ 2024-03-21 2792/week @ 2024-03-28 2519/week @ 2024-04-04 2442/week @ 2024-04-11 3245/week @ 2024-04-18 2500/week @ 2024-04-25 1803/week @ 2024-05-02 3011/week @ 2024-05-09 2393/week @ 2024-05-16 2645/week @ 2024-05-23 3338/week @ 2024-05-30 2239/week @ 2024-06-06 3725/week @ 2024-06-13 3816/week @ 2024-06-20 2468/week @ 2024-06-27

12,902 每月下载量
34 个库中(直接使用6个) 使用

Apache-2.0

64KB
1.5K SLoC

prometheus-static-metric

docs.rs

用于为 rust-prometheus 库构建静态度量的实用宏。

为什么?

MetricVec(即 CounterVecGaugeVecHistogramVec)较慢。然而,如果已知标签的所有可能值,则 MetricVec 中的每个度量都可以被缓存,以避免运行时成本。

例如,以下代码在多次调用时可能较慢

some_counter_vec.with_label_values(&["label_1_foo", "label_2_bar"]).inc();

这是因为我们每次根据值检索特定的 Counter,为了确保线程安全,在锁内部进行操作,这使情况变得更糟。

我们可以通过按标签值缓存计数器来优化它

// init before hand
let foo_bar_counter = some_counter.with_label_values(&["label_1_foo", "label_2_bar"]);

foo_bar_counter.inc();

到目前为止,一切看起来都很好。我们实现了与 Counter 相同的性能,对于 CounterVec。但如果有很多标签,并且每个标签都有很多值怎么办?我们需要手工编写大量的代码来实现这一点。

这正是这个库解决的问题。这个库提供了一个宏,帮助您在不引入大量模板代码的情况下执行上述优化。

入门

  • 添加到 Cargo.toml

    [dependencies]
    prometheus-static-metric = "0.4"
    
  • 添加到 lib.rs

    extern crate prometheus_static_metric;
    

示例

使用 make_static_metric! 定义每个标签的所有可能值。您的定义将被扩展为一个真实的 struct,以便于访问,同时保持高性能。

use prometheus_static_metric::make_static_metric;

make_static_metric! {
    pub struct MyStaticCounterVec: Counter {
        "method" => {
            post,
            get,
            put,
            delete,
        },
        "product" => {
            foo,
            bar,
        },
    }
}

fn main() {
    let vec = CounterVec::new(Opts::new("foo", "bar"), &["method", "product"]).unwrap();
    let static_counter_vec = MyStaticCounterVec::from(&vec);

    static_counter_vec.post.foo.inc();
    static_counter_vec.delete.bar.inc_by(4.0);
    assert_eq!(static_counter_vec.post.bar.get(), 0.0);
    assert_eq!(vec.with_label_values(&["post", "foo"]).get(), 1.0);
    assert_eq!(vec.with_label_values(&["delete", "bar"]).get(), 4.0);
}

自动刷新的本地线程指标

对于全局共享静态指标可能效率不足的重型场景,您可以使用 make_auto_flush_static_metric! 宏,该宏将数据存储在本地线程存储中,并自定义刷新到全局 MetricVec 的速率。

#[macro_use]
extern crate lazy_static;
extern crate prometheus;
extern crate prometheus_static_metric;

use prometheus::*;
use prometheus_static_metric::auto_flush_from;
use prometheus_static_metric::make_auto_flush_static_metric;

make_auto_flush_static_metric! {

    pub label_enum FooBar {
        foo,
        bar,
    }

    pub label_enum Methods {
        post,
        get,
        put,
        delete,
    }

    pub struct Lhrs: LocalIntCounter {
        "product" => FooBar,
        "method" => Methods,
        "version" => {
            http1: "HTTP/1",
            http2: "HTTP/2",
        },
    }
}

lazy_static! {
    pub static ref HTTP_COUNTER_VEC: IntCounterVec =
        register_int_counter_vec ! (
            "http_requests_total",
            "Number of HTTP requests.",
            & ["product", "method", "version"]    // it doesn't matter for the label order
        ).unwrap();
}

lazy_static! {
    // You can also use default flush duration which is 1 second.
    // pub static ref TLS_HTTP_COUNTER: Lhrs = auto_flush_from!(HTTP_COUNTER_VEC, Lhrs);
    pub static ref TLS_HTTP_COUNTER: Lhrs = auto_flush_from!(HTTP_COUNTER_VEC, Lhrs, std::time::Duration::from_secs(1));
}

fn main() {
    TLS_HTTP_COUNTER.foo.post.http1.inc();
    TLS_HTTP_COUNTER.foo.post.http1.inc();

    assert_eq!(
        HTTP_COUNTER_VEC
            .with_label_values(&["foo", "post", "HTTP/1"])
            .get(),
        0
    );

    ::std::thread::sleep(::std::time::Duration::from_secs(2));

    TLS_HTTP_COUNTER.foo.post.http1.inc();
    assert_eq!(
        HTTP_COUNTER_VEC
            .with_label_values(&["foo", "post", "HTTP/1"])
            .get(),
        3
    );
}

请查看 示例目录 以获取更多信息。

依赖项

~1.5MB
~35K SLoC