#metrics #macro #instrument #execution-time

function-timer

Macro that allow to time a function and emit a metric using metrics crate

8 releases (breaking)

0.8.0 Jun 3, 2024
0.7.0 Jan 19, 2024
0.6.0 Apr 17, 2023
0.5.0 Apr 7, 2023
0.1.0 Mar 1, 2023

#84 in Profiling

Download history 11/week @ 2024-03-14 3/week @ 2024-03-21 25/week @ 2024-03-28 24/week @ 2024-04-04 1/week @ 2024-04-11 1/week @ 2024-04-18 136/week @ 2024-05-30 31/week @ 2024-06-06 3/week @ 2024-06-13 19/week @ 2024-06-20 18/week @ 2024-06-27

80 downloads per month

MIT/Apache

18KB
52 lines

Crate Build Status codecov dependency status Documentation Crate Crate

Function timer

Macro that allows to time a function and emit a histogram metric using metrics crate.

Note: with the use of another attribut macro, declaration order might matter. Especially using async-trait, depending on which one is first, you time the actual execution of the function if time macro is declared before, or the creation of the future if it's declared after.

Example

use std::error::Error;
use metrics_exporter_prometheus::PrometheusBuilder;
use function_timer::time;

struct Test {}

impl Test {
    #[time("my_metric")]
    pub fn impl_function(&self) {
        println!("This another test");
    }

    #[time("another_metric")]
    pub fn impl_fail_function(&self, text:&str) -> Result<(), Box<dyn Error>>{
        let number:usize = text.parse()?;
        println!("{number}");

        Ok(())
    }

    #[time("my_metric")]
    pub fn static_function() {
        println!("This another test");
    }
}

#[time("my_metric")]
pub fn free_function() {
    println!("This a test");
}

fn main() -> Result<(), Box<dyn Error>> {
    let builder = PrometheusBuilder::new();
    let handle = builder.install_recorder()?;

    free_function();

    Test::static_function();

    let t = Test {};
    t.impl_function();

    let result = t.impl_fail_function("azerty");
    assert!(result.is_err());
    let result = t.impl_fail_function("1");
    assert!(result.is_ok());


    println!("{}", handle.render());

    Ok(())
}

Output :

This a test
This another test
This another test
1
# TYPE another_metric summary
another_metric{function="impl_fail_function",quantile="0"} 0.000000677
another_metric{function="impl_fail_function",quantile="0.5"} 0.0000006770639874327633
another_metric{function="impl_fail_function",quantile="0.9"} 0.0000006770639874327633
another_metric{function="impl_fail_function",quantile="0.95"} 0.0000006770639874327633
another_metric{function="impl_fail_function",quantile="0.99"} 0.0000006770639874327633
another_metric{function="impl_fail_function",quantile="0.999"} 0.0000006770639874327633
another_metric{function="impl_fail_function",quantile="1"} 0.000012062
another_metric_sum{function="impl_fail_function"} 0.000012739000000000001
another_metric_count{function="impl_fail_function"} 2

# TYPE my_metric summary
my_metric{function="free_function",quantile="0"} 0.000005702
my_metric{function="free_function",quantile="0.5"} 0.000005701963063845405
my_metric{function="free_function",quantile="0.9"} 0.000005701963063845405
my_metric{function="free_function",quantile="0.95"} 0.000005701963063845405
my_metric{function="free_function",quantile="0.99"} 0.000005701963063845405
my_metric{function="free_function",quantile="0.999"} 0.000005701963063845405
my_metric{function="free_function",quantile="1"} 0.000005702
my_metric_sum{function="free_function"} 0.000005702
my_metric_count{function="free_function"} 1
my_metric{function="impl_function",quantile="0"} 0.000002602
my_metric{function="impl_function",quantile="0.5"} 0.0000026018182046361393
my_metric{function="impl_function",quantile="0.9"} 0.0000026018182046361393
my_metric{function="impl_function",quantile="0.95"} 0.0000026018182046361393
my_metric{function="impl_function",quantile="0.99"} 0.0000026018182046361393
my_metric{function="impl_function",quantile="0.999"} 0.0000026018182046361393
my_metric{function="impl_function",quantile="1"} 0.000002602
my_metric_sum{function="impl_function"} 0.000002602
my_metric_count{function="impl_function"} 1
my_metric{function="static_function",quantile="0"} 0.000002894
my_metric{function="static_function",quantile="0.5"} 0.0000028939157344447597
my_metric{function="static_function",quantile="0.9"} 0.0000028939157344447597
my_metric{function="static_function",quantile="0.95"} 0.0000028939157344447597
my_metric{function="static_function",quantile="0.99"} 0.0000028939157344447597
my_metric{function="static_function",quantile="0.999"} 0.0000028939157344447597
my_metric{function="static_function",quantile="1"} 0.000002894
my_metric_sum{function="static_function"} 0.000002894
my_metric_count{function="static_function"} 1

It can also be put on an impl block :

use std::error::Error;
use metrics_exporter_prometheus::PrometheusBuilder;
use function_timer::time;

struct Test {}

#[time("my_metric")]
impl Test {
    pub fn impl_function(&self) {
        println!("This another test");
    }

    pub fn impl_fail_function(&self, text:&str) -> Result<(), Box<dyn Error>>{
        let number:usize = text.parse()?;
        println!("{number}");

        Ok(())
    }

    pub fn static_function() {
        println!("This another test");
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let builder = PrometheusBuilder::new();
    let handle = builder.install_recorder()?;

    Test::static_function();

    let t = Test {};
    t.impl_function();

    let result = t.impl_fail_function("azerty");
    assert!(result.is_err());
    let result = t.impl_fail_function("1");
    assert!(result.is_ok());


    println!("{}", handle.render());

    Ok(())
}

It will output :

This another test
This another test
1
# TYPE my_metric summary
my_metric{struct="Test",function="static_function",quantile="0"} 0.000005976
my_metric{struct="Test",function="static_function",quantile="0.5"} 0.000005976352983111928
my_metric{struct="Test",function="static_function",quantile="0.9"} 0.000005976352983111928
my_metric{struct="Test",function="static_function",quantile="0.95"} 0.000005976352983111928
my_metric{struct="Test",function="static_function",quantile="0.99"} 0.000005976352983111928
my_metric{struct="Test",function="static_function",quantile="0.999"} 0.000005976352983111928
my_metric{struct="Test",function="static_function",quantile="1"} 0.000005976
my_metric_sum{struct="Test",function="static_function"} 0.000005976
my_metric_count{struct="Test",function="static_function"} 1
my_metric{struct="Test",function="impl_fail_function",quantile="0"} 0.000000771
my_metric{struct="Test",function="impl_fail_function",quantile="0.5"} 0.0000007710596865495025
my_metric{struct="Test",function="impl_fail_function",quantile="0.9"} 0.0000007710596865495025
my_metric{struct="Test",function="impl_fail_function",quantile="0.95"} 0.0000007710596865495025
my_metric{struct="Test",function="impl_fail_function",quantile="0.99"} 0.0000007710596865495025
my_metric{struct="Test",function="impl_fail_function",quantile="0.999"} 0.0000007710596865495025
my_metric{struct="Test",function="impl_fail_function",quantile="1"} 0.00000257
my_metric_sum{struct="Test",function="impl_fail_function"} 0.000003341
my_metric_count{struct="Test",function="impl_fail_function"} 2
my_metric{struct="Test",function="impl_function",quantile="0"} 0.000003853
my_metric{struct="Test",function="impl_function",quantile="0.5"} 0.000003852839894857494
my_metric{struct="Test",function="impl_function",quantile="0.9"} 0.000003852839894857494
my_metric{struct="Test",function="impl_function",quantile="0.95"} 0.000003852839894857494
my_metric{struct="Test",function="impl_function",quantile="0.99"} 0.000003852839894857494
my_metric{struct="Test",function="impl_function",quantile="0.999"} 0.000003852839894857494
my_metric{struct="Test",function="impl_function",quantile="1"} 0.000003853
my_metric_sum{struct="Test",function="impl_function"} 0.000003853
my_metric_count{struct="Test",function="impl_function"} 1

Dependencies

~1.1–1.8MB
~32K SLoC