fuel_core_metrics/
graphql_metrics.rs

1use crate::{
2    buckets::{
3        buckets,
4        Buckets,
5    },
6    global_registry,
7};
8use prometheus_client::{
9    encoding::EncodeLabelSet,
10    metrics::{
11        family::Family,
12        gauge::Gauge,
13        histogram::Histogram,
14    },
15};
16use std::sync::OnceLock;
17
18#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
19pub struct Label {
20    // the graphql path
21    path: String,
22}
23
24pub struct GraphqlMetrics {
25    // using gauges in case blocks are rolled back for any reason
26    pub total_txs_count: Gauge,
27    requests: Family<Label, Histogram>,
28    queries_complexity: Histogram,
29}
30
31impl GraphqlMetrics {
32    fn new() -> Self {
33        let tx_count_gauge = Gauge::default();
34        let queries_complexity = Histogram::new(buckets_complexity());
35        let requests = Family::<Label, Histogram>::new_with_constructor(|| {
36            Histogram::new(buckets(Buckets::Timing))
37        });
38        let mut registry = global_registry().registry.lock();
39        registry.register("graphql_request_duration_seconds", "", requests.clone());
40        registry.register(
41            "graphql_query_complexity",
42            "The complexity of all queries received",
43            queries_complexity.clone(),
44        );
45
46        registry.register(
47            "importer_tx_count",
48            "the total amount of transactions that have been imported on chain",
49            tx_count_gauge.clone(),
50        );
51
52        Self {
53            total_txs_count: tx_count_gauge,
54            queries_complexity,
55            requests,
56        }
57    }
58
59    pub fn graphql_observe(&self, query: &str, time: f64) {
60        let histogram = self.requests.get_or_create(&Label {
61            path: query.to_string(),
62        });
63        histogram.observe(time);
64    }
65
66    pub fn graphql_complexity_observe(&self, complexity: f64) {
67        self.queries_complexity.observe(complexity);
68    }
69}
70
71static GRAPHQL_METRICS: OnceLock<GraphqlMetrics> = OnceLock::new();
72pub fn graphql_metrics() -> &'static GraphqlMetrics {
73    GRAPHQL_METRICS.get_or_init(GraphqlMetrics::new)
74}
75
76fn buckets_complexity() -> impl Iterator<Item = f64> {
77    [
78        1_000.0,
79        5_000.0,
80        10_000.0,
81        20_000.0,
82        50_000.0,
83        100_000.0,
84        250_000.0,
85        500_000.0,
86        1_000_000.0,
87        5_000_000.0,
88        10_000_000.0,
89    ]
90    .into_iter()
91}