iota_proxy/
handlers.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::net::SocketAddr;
6
7use axum::{
8    extract::{ConnectInfo, Extension},
9    http::StatusCode,
10};
11use multiaddr::Multiaddr;
12use once_cell::sync::Lazy;
13use prometheus::{CounterVec, HistogramVec, register_counter_vec, register_histogram_vec};
14
15use crate::{
16    admin::{Labels, ReqwestClient},
17    consumer::{NodeMetric, convert_to_remote_write, populate_labels},
18    histogram_relay::HistogramRelay,
19    middleware::LenDelimProtobuf,
20    peers::IotaPeer,
21};
22
23static HANDLER_HITS: Lazy<CounterVec> = Lazy::new(|| {
24    register_counter_vec!(
25        "http_handler_hits",
26        "Number of HTTP requests made.",
27        &["handler", "remote"]
28    )
29    .unwrap()
30});
31
32static HTTP_HANDLER_DURATION: Lazy<HistogramVec> = Lazy::new(|| {
33    register_histogram_vec!(
34        "http_handler_duration_seconds",
35        "The HTTP request latencies in seconds.",
36        &["handler", "remote"],
37        vec![
38            1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5, 4.75,
39            5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0
40        ],
41    )
42    .unwrap()
43});
44
45/// Publish handler which receives metrics from nodes.  Nodes will call us at
46/// this endpoint and we relay them to the upstream tsdb
47///
48/// Clients will receive a response after successfully relaying the metrics
49/// upstream
50pub async fn publish_metrics(
51    Extension(labels): Extension<Labels>,
52    Extension(client): Extension<ReqwestClient>,
53    ConnectInfo(addr): ConnectInfo<SocketAddr>,
54    Extension(IotaPeer { name, public_key }): Extension<IotaPeer>,
55    Extension(relay): Extension<HistogramRelay>,
56    LenDelimProtobuf(data): LenDelimProtobuf,
57) -> (StatusCode, &'static str) {
58    HANDLER_HITS
59        .with_label_values(&["publish_metrics", &name])
60        .inc();
61    let timer = HTTP_HANDLER_DURATION
62        .with_label_values(&["publish_metrics", &name])
63        .start_timer();
64    let data = populate_labels(name, labels.network, data);
65    relay.submit(data.clone());
66    let response = convert_to_remote_write(
67        client.clone(),
68        NodeMetric {
69            data,
70            peer_addr: Multiaddr::from(addr.ip()),
71            public_key,
72        },
73    )
74    .await;
75    timer.observe_duration();
76    response
77}