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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
//! raftlog のメトリクス。

use prometrics::metrics::{Counter, Gauge, Histogram, HistogramBuilder, MetricBuilder};

use {Error, Result};

/// `raftlog` 全体に関するメトリクス。
#[derive(Clone)]
pub struct RaftlogMetrics {
    pub(crate) node_state: NodeStateMetrics,
}
impl RaftlogMetrics {
    pub(crate) fn new(builder: &MetricBuilder) -> Result<Self> {
        let node_state = track!(NodeStateMetrics::new(builder))?;
        Ok(Self { node_state })
    }
}

/// ノード状態に関するメトリクス。
#[derive(Clone)]
pub struct NodeStateMetrics {
    pub(crate) transit_to_candidate_total: Counter,
    pub(crate) transit_to_follower_total: Counter,
    pub(crate) transit_to_leader_total: Counter,
    pub(crate) event_queue_len: Gauge,
    pub(crate) poll_timeout_total: Counter,
    pub(crate) candidate_to_leader_duration_seconds: Histogram,
    pub(crate) candidate_to_follower_duration_seconds: Histogram,
    pub(crate) loader_to_candidate_duration_seconds: Histogram,
}
impl NodeStateMetrics {
    pub(crate) fn new(builder: &MetricBuilder) -> Result<Self> {
        let mut builder: MetricBuilder = builder.clone();
        builder.subsystem("node_state");
        let transit_to_candidate_total = track!(builder
            .counter("transit_to_candidate_total")
            .help("Number of transitions to candidate role")
            .finish())?;
        let transit_to_follower_total = track!(builder
            .counter("transit_to_follower_total")
            .help("Number of transitions to follower role")
            .finish())?;
        let transit_to_leader_total = track!(builder
            .counter("transit_to_leader_total")
            .help("Number of transitions to leader role")
            .finish())?;
        let event_queue_len = track!(builder
            .gauge("event_queue_len")
            .help("Length of a raft event queue")
            .finish())?;
        let poll_timeout_total = track!(builder
            .counter("poll_timeout_total")
            .help("Number of timeout")
            .finish())?;
        let candidate_to_leader_duration_seconds = track!(make_role_change_histogram(
            builder
                .histogram("candidate_to_leader_duration_seconds")
                .help("Elapsed time moving from candidate to leader")
        ))?;
        let candidate_to_follower_duration_seconds = track!(make_role_change_histogram(
            builder
                .histogram("candidate_to_follower_duration_seconds")
                .help("Elapsed time moving from candidate to follower")
        ))?;
        let loader_to_candidate_duration_seconds = track!(make_role_change_histogram(
            builder
                .histogram("loader_to_candidate_duration_seconds")
                .help("Elapsed time moving from loader to candidate")
        ))?;
        Ok(Self {
            transit_to_candidate_total,
            transit_to_follower_total,
            transit_to_leader_total,
            event_queue_len,
            poll_timeout_total,
            candidate_to_leader_duration_seconds,
            candidate_to_follower_duration_seconds,
            loader_to_candidate_duration_seconds,
        })
    }
}

fn make_role_change_histogram(builder: &mut HistogramBuilder) -> Result<Histogram> {
    builder
        .bucket(0.001)
        .bucket(0.005)
        .bucket(0.01)
        .bucket(0.05)
        .bucket(0.1)
        .bucket(0.2)
        .bucket(0.4)
        .bucket(0.6)
        .bucket(0.8)
        .bucket(1.0)
        .bucket(2.0)
        .bucket(4.0)
        .bucket(6.0)
        .bucket(8.0)
        .bucket(10.0)
        .bucket(20.0)
        .bucket(50.0)
        .bucket(80.0)
        .bucket(320.0)
        .bucket(640.0)
        .finish()
        .map_err(|e| track!(Error::from(e)))
}