fuel_core_metrics/
graphql_metrics.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::{
    buckets::{
        buckets,
        Buckets,
    },
    global_registry,
};
use prometheus_client::{
    encoding::EncodeLabelSet,
    metrics::{
        family::Family,
        gauge::Gauge,
        histogram::Histogram,
    },
};
use std::sync::OnceLock;

#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
pub struct Label {
    // the graphql path
    path: String,
}

pub struct GraphqlMetrics {
    // using gauges in case blocks are rolled back for any reason
    pub total_txs_count: Gauge,
    requests: Family<Label, Histogram>,
    queries_complexity: Histogram,
}

impl GraphqlMetrics {
    fn new() -> Self {
        let tx_count_gauge = Gauge::default();
        let queries_complexity = Histogram::new(buckets_complexity());
        let requests = Family::<Label, Histogram>::new_with_constructor(|| {
            Histogram::new(buckets(Buckets::Timing))
        });
        let mut registry = global_registry().registry.lock();
        registry.register("graphql_request_duration_seconds", "", requests.clone());
        registry.register(
            "graphql_query_complexity",
            "The complexity of all queries received",
            queries_complexity.clone(),
        );

        registry.register(
            "importer_tx_count",
            "the total amount of transactions that have been imported on chain",
            tx_count_gauge.clone(),
        );

        Self {
            total_txs_count: tx_count_gauge,
            queries_complexity,
            requests,
        }
    }

    pub fn graphql_observe(&self, query: &str, time: f64) {
        let histogram = self.requests.get_or_create(&Label {
            path: query.to_string(),
        });
        histogram.observe(time);
    }

    pub fn graphql_complexity_observe(&self, complexity: f64) {
        self.queries_complexity.observe(complexity);
    }
}

static GRAPHQL_METRICS: OnceLock<GraphqlMetrics> = OnceLock::new();
pub fn graphql_metrics() -> &'static GraphqlMetrics {
    GRAPHQL_METRICS.get_or_init(GraphqlMetrics::new)
}

fn buckets_complexity() -> impl Iterator<Item = f64> {
    [
        1_000.0,
        5_000.0,
        10_000.0,
        20_000.0,
        50_000.0,
        100_000.0,
        250_000.0,
        500_000.0,
        1_000_000.0,
        5_000_000.0,
        10_000_000.0,
    ]
    .into_iter()
}