Skip to content

Commit fd2769a

Browse files
ruudaenriquefynn
authored andcommitted
Expose epoch schedule metrics in Prometheus
With the epoch start slots and the number of slots in the epoch (and the current slot, which we already had), we can infer/estimate: * Epoch progress percentage * Slots left until the next epoch * Time left until the next epoch (from slot height increase) These are useful metrics to have about the network.
1 parent 3b7a516 commit fd2769a

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

prometheus/src/bank_metrics.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use crate::{
33
utils::{write_metric, Metric, MetricFamily},
44
};
55
use std::io;
6+
use solana_sdk::sysvar;
7+
use solana_sdk::sysvar::epoch_schedule::EpochSchedule;
68

79
pub fn write_bank_metrics<W: io::Write>(
810
banks_with_commitments: &BanksWithCommitments,
@@ -28,6 +30,46 @@ pub fn write_bank_metrics<W: io::Write>(
2830
.for_each_commitment(|bank| Some(Metric::new(bank.clock().epoch))),
2931
},
3032
)?;
33+
write_metric(
34+
out,
35+
&MetricFamily {
36+
name: "solana_block_epoch_start_slot",
37+
help: "The first slot in the current epoch",
38+
type_: "gauge",
39+
metrics: banks_with_commitments
40+
.for_each_commitment(|bank| {
41+
// Note, the bank actually has a field that holds the EpochSchedule,
42+
// but it is not public, so we can't easily access it here. We could
43+
// make it public, but to make our patches less invasive, load the
44+
// epoch schedule from the sysvar instead. It should always exist.
45+
let epoch_schedule: EpochSchedule = bank
46+
.get_account(&sysvar::epoch_schedule::id())?
47+
.deserialize_data().ok()?;
48+
let clock = bank.clock();
49+
Some(Metric::new(epoch_schedule.get_first_slot_in_epoch(clock.epoch)))
50+
}),
51+
},
52+
)?;
53+
write_metric(
54+
out,
55+
&MetricFamily {
56+
name: "solana_block_epoch_slots_total",
57+
help: "The duration of the current epoch, in slots.",
58+
type_: "gauge",
59+
metrics: banks_with_commitments
60+
.for_each_commitment(|bank| {
61+
// Note, the bank actually has a field that holds the EpochSchedule,
62+
// but it is not public, so we can't easily access it here. We could
63+
// make it public, but to make our patches less invasive, load the
64+
// epoch schedule from the sysvar instead. It should always exist.
65+
let epoch_schedule: EpochSchedule = bank
66+
.get_account(&sysvar::epoch_schedule::id())?
67+
.deserialize_data().ok()?;
68+
let clock = bank.clock();
69+
Some(Metric::new(epoch_schedule.get_slots_in_epoch(clock.epoch)))
70+
}),
71+
},
72+
)?;
3173
write_metric(
3274
out,
3375
&MetricFamily {

0 commit comments

Comments
 (0)