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
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

use mz_ore::metric;
use mz_ore::metrics::raw::IntCounterVec;
use mz_ore::metrics::{IntCounter, MetricsRegistry};

#[derive(Clone, Debug)]
pub struct MetricsConfig {
    connection_status: IntCounterVec,
}

impl MetricsConfig {
    pub fn register_into(registry: &MetricsRegistry) -> Self {
        Self {
            connection_status: registry.register(metric! {
                name: "mz_connection_status",
                help: "Count of completed network connections, by status",
                var_labels: ["source", "status"],
            }),
        }
    }
}

#[derive(Clone, Debug)]
pub struct Metrics {
    inner: MetricsConfig,
    label: &'static str,
}

impl Metrics {
    pub fn new(inner: MetricsConfig, label: &'static str) -> Self {
        let self_ = Self { inner, label };

        // pre-initialize labels we are planning to use to ensure they are all
        // always emitted as time series
        self_.connection_status(false);
        self_.connection_status(true);

        self_
    }

    pub fn connection_status(&self, is_ok: bool) -> IntCounter {
        self.inner
            .connection_status
            .with_label_values(&[self.source_label(), Self::status_label(is_ok)])
    }

    fn status_label(is_ok: bool) -> &'static str {
        if is_ok {
            "success"
        } else {
            "error"
        }
    }

    fn source_label(&self) -> &'static str {
        self.label
    }
}