-
Notifications
You must be signed in to change notification settings - Fork 296
/
lib.rs
144 lines (127 loc) · 5.6 KB
/
lib.rs
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use ic_base_types::{CanisterId, PrincipalId};
use ic_nervous_system_proxied_canister_calls_tracker::ProxiedCanisterCallsTracker;
use ic_nns_constants::{
CYCLES_MINTING_CANISTER_ID, EXCHANGE_RATE_CANISTER_ID, GENESIS_TOKEN_CANISTER_ID,
GOVERNANCE_CANISTER_ID, IDENTITY_CANISTER_ID, LEDGER_CANISTER_ID, LIFELINE_CANISTER_ID,
NNS_UI_CANISTER_ID, REGISTRY_CANISTER_ID, ROOT_CANISTER_ID, SNS_WASM_CANISTER_ID,
};
use lazy_static::lazy_static;
use maplit::btreemap;
use std::{cell::RefCell, collections::BTreeMap};
pub mod canister_management;
pub mod init;
pub mod pb;
pub mod root_proposals;
thread_local! {
// TODO: Move this to canister.rs. It needs to be here for now, because
// other libs want to use this. Ideally, this would only be passed to the
// constructor of TrackingManagementCanisterClient.
pub static PROXIED_CANISTER_CALLS_TRACKER: RefCell<ProxiedCanisterCallsTracker> =
RefCell::new(ProxiedCanisterCallsTracker::new(dfn_core::api::now));
}
/// Encode the metrics in a format that can be understood by Prometheus.
pub fn encode_metrics(w: &mut ic_metrics_encoder::MetricsEncoder<Vec<u8>>) -> std::io::Result<()> {
PROXIED_CANISTER_CALLS_TRACKER.with(|proxied_canister_calls_tracker| {
let proxied_canister_calls_tracker = proxied_canister_calls_tracker.borrow();
let mut metric_builder = w.gauge_vec(
"nns_root_in_flight_proxied_canister_call_max_age_seconds",
"The age of incomplete canister calls that are being made on \
behalf of another NNS canisters, usually NNS governance.",
)?;
for (key, max_age) in
proxied_canister_calls_tracker.get_method_name_caller_callee_to_in_flight_max_age()
{
let (method_name, caller, callee) = key;
metric_builder = metric_builder.value(
&[
("caller", &principal_name(caller)),
("callee", &principal_name(callee.get())),
("method_name", &method_name),
],
max_age.as_secs_f64(),
)?;
}
let mut metrics = w.gauge_vec(
"nns_root_in_flight_proxied_canister_call_count",
"The number of proxied canister calls that are in flight and being made \
on behalf of another (NNS) canister.",
)?;
let in_flight_counts =
proxied_canister_calls_tracker.get_method_name_caller_callee_to_in_flight_count();
for ((method_name, caller, callee), count) in &in_flight_counts {
metrics = metrics.value(
&[
("method_name", method_name),
("caller", &principal_name(*caller)),
("callee", &principal_name(callee.get())),
],
*count as f64,
)?;
}
// All of the following metrics are superseded (by nns_root_in_flight_proxied_canister_call_count).
let canister_status_caller_to_in_flight_count = {
// I am not sure if this fact is in the spec, but it is in the code.
let min_principal_id = CanisterId::ic_00().get();
// This is the range where method_name == "canister_status".
let begin = (
"canister_status".to_string(),
min_principal_id,
CanisterId::ic_00(),
);
let end = (
"canister_status\0".to_string(),
min_principal_id,
CanisterId::ic_00(),
);
in_flight_counts
.range(begin..end)
.map(|((_, caller, _), count)| (*caller, *count))
.collect::<BTreeMap<PrincipalId, u64>>()
};
w.encode_gauge(
"nns_root_open_canister_status_calls_count",
canister_status_caller_to_in_flight_count
.values()
.sum::<u64>() as f64,
"Superseded by nns_root_in_flight_proxied_canister_call_count. \
Count of open CanisterStatusCalls.",
)?;
let mut metrics = w.gauge_vec(
"nns_root_open_canister_status_calls",
"Superseded by nns_root_in_flight_proxied_canister_call_count. \
The list of counters and canister_ids with open canister_status calls.",
)?;
for (canister_id, call_count) in &canister_status_caller_to_in_flight_count {
metrics = metrics.value(
&[("canister_id", &format!("{}", canister_id))],
(*call_count) as f64,
)?;
}
std::io::Result::Ok(())
})?;
Ok(())
}
fn principal_name(principal_id: PrincipalId) -> String {
lazy_static! {
static ref CANISTER_ID_TO_NAME: BTreeMap<CanisterId, &'static str> = btreemap! {
CanisterId::ic_00() => "management",
REGISTRY_CANISTER_ID => "registry",
GOVERNANCE_CANISTER_ID => "governance",
LEDGER_CANISTER_ID => "ledger",
ROOT_CANISTER_ID => "root",
CYCLES_MINTING_CANISTER_ID => "cycles_minting",
LIFELINE_CANISTER_ID => "lifeline",
GENESIS_TOKEN_CANISTER_ID => "genesis_token",
IDENTITY_CANISTER_ID => "identity",
NNS_UI_CANISTER_ID => "nns_ui",
SNS_WASM_CANISTER_ID => "sns_wasm",
EXCHANGE_RATE_CANISTER_ID => "exchange_rate",
};
}
Some(CanisterId::unchecked_from_principal(principal_id))
.and_then(|canister_id| CANISTER_ID_TO_NAME.get(&canister_id))
.map(|name| format!("{}_canister", name))
.unwrap_or_else(|| principal_id.to_string())
}
#[cfg(test)]
mod tests;