Skip to main content

pharos_plugins/
prometheus.rs

1//! Prometheus Directive configuration.
2
3use pharos_corefile::{Cursor, Error};
4use pharos_server::{Context, Next, Outcome, Plugin};
5
6#[derive(Debug)]
7pub struct Prometheus {
8    pub address: String,
9    pub tls_config: Option<String>,
10}
11
12pub(crate) fn parse(cursor: &mut Cursor<'_>) -> Result<Prometheus, Error> {
13    cursor.next();
14    let args = cursor.remaining_args();
15    if args.len() > 1 {
16        return Err(cursor.arg_err());
17    }
18    let address = args.first().map_or("localhost:9153", String::as_str);
19    if !crate::valid_http_address(address) {
20        return Err(cursor.error("invalid metrics address"));
21    }
22    let mut tls_config = None;
23    while cursor.next_block() {
24        match cursor.val() {
25            "runtime_metrics" => {
26                if !cursor.remaining_args().is_empty() {
27                    return Err(cursor.arg_err());
28                }
29            }
30            "tls" => {
31                if tls_config.is_some() {
32                    return Err(cursor.error("tls block already specified"));
33                }
34                let args = cursor.remaining_args();
35                if args.len() != 1 {
36                    return Err(cursor.arg_err());
37                }
38                tls_config = Some(args[0].clone());
39            }
40            option => return Err(cursor.error(format!("unknown option: {option}"))),
41        }
42    }
43    Ok(Prometheus {
44        address: address.to_owned(),
45        tls_config,
46    })
47}
48
49impl Plugin for Prometheus {
50    async fn serve<N: Next + Send>(&self, cx: &mut Context<'_>, next: N) -> Outcome {
51        next.run(cx).await
52    }
53}