1
// Copyright (C) Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

            
4
// Polkadot is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Polkadot is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Runtime metric primitives.
18

            
19
use alloc::vec::Vec;
20
use codec::{Decode, Encode};
21

            
22
/// Runtime metric operations.
23
#[derive(Encode, Decode)]
24
#[cfg_attr(feature = "std", derive(Debug))]
25
pub enum RuntimeMetricOp {
26
	/// Increment a counter metric with labels by value.
27
	IncrementCounterVec(u64, RuntimeMetricLabelValues),
28
	/// Increment a counter metric by value.
29
	IncrementCounter(u64),
30
	/// Observe histogram value
31
	ObserveHistogram(u128),
32
}
33

            
34
/// Runtime metric update event.
35
#[derive(Encode, Decode)]
36
#[cfg_attr(feature = "std", derive(Debug))]
37
pub struct RuntimeMetricUpdate {
38
	/// The name of the metric.
39
	pub metric_name: Vec<u8>,
40
	/// The operation applied to the metric.
41
	pub op: RuntimeMetricOp,
42
}
43

            
44
fn vec_to_str<'a>(v: &'a Vec<u8>, default: &'static str) -> &'a str {
45
	return alloc::str::from_utf8(v).unwrap_or(default)
46
}
47

            
48
impl RuntimeMetricLabels {
49
	/// Returns a labels as `Vec<&str>`.
50
	pub fn as_str_vec(&self) -> Vec<&str> {
51
		self.0
52
			.iter()
53
			.map(|label_vec| vec_to_str(&label_vec.0, "invalid_label"))
54
			.collect()
55
	}
56

            
57
	/// Return the inner values as vec.
58
	pub fn clear(&mut self) {
59
		self.0.clear();
60
	}
61
}
62

            
63
impl From<&[&'static str]> for RuntimeMetricLabels {
64
	fn from(v: &[&'static str]) -> RuntimeMetricLabels {
65
		RuntimeMetricLabels(
66
			v.iter().map(|label| RuntimeMetricLabel(label.as_bytes().to_vec())).collect(),
67
		)
68
	}
69
}
70

            
71
impl RuntimeMetricUpdate {
72
	/// Returns the metric name.
73
	pub fn metric_name(&self) -> &str {
74
		vec_to_str(&self.metric_name, "invalid_metric_name")
75
	}
76
}
77

            
78
/// A set of metric labels.
79
#[derive(Clone, Default, Encode, Decode)]
80
#[cfg_attr(feature = "std", derive(Debug))]
81
pub struct RuntimeMetricLabels(Vec<RuntimeMetricLabel>);
82

            
83
/// A metric label.
84
#[derive(Clone, Default, Encode, Decode)]
85
#[cfg_attr(feature = "std", derive(Debug))]
86
pub struct RuntimeMetricLabel(Vec<u8>);
87

            
88
/// A metric label value.
89
pub type RuntimeMetricLabelValue = RuntimeMetricLabel;
90

            
91
/// A set of metric label values.
92
pub type RuntimeMetricLabelValues = RuntimeMetricLabels;
93

            
94
/// Trait for converting Vec<u8> to `&str`.
95
pub trait AsStr {
96
	/// Return a str reference.
97
	fn as_str(&self) -> Option<&str>;
98
}
99

            
100
impl AsStr for RuntimeMetricLabel {
101
	fn as_str(&self) -> Option<&str> {
102
		alloc::str::from_utf8(&self.0).ok()
103
	}
104
}
105

            
106
impl From<&'static str> for RuntimeMetricLabel {
107
	fn from(s: &'static str) -> Self {
108
		Self(s.as_bytes().to_vec())
109
	}
110
}
111

            
112
/// Contains all runtime metrics defined as constants.
113
pub mod metric_definitions {
114
	/// `Counter` metric definition.
115
	pub struct CounterDefinition {
116
		/// The name of the metric.
117
		pub name: &'static str,
118
		/// The description of the metric.
119
		pub description: &'static str,
120
	}
121

            
122
	/// `CounterVec` metric definition.
123
	pub struct CounterVecDefinition<'a> {
124
		/// The name of the metric.
125
		pub name: &'static str,
126
		/// The description of the metric.
127
		pub description: &'static str,
128
		/// The label names of the metric.
129
		pub labels: &'a [&'static str],
130
	}
131

            
132
	/// `Histogram` metric definition
133
	pub struct HistogramDefinition<'a> {
134
		/// The name of the metric.
135
		pub name: &'static str,
136
		/// The description of the metric.
137
		pub description: &'static str,
138
		/// The buckets for the histogram
139
		pub buckets: &'a [f64],
140
	}
141

            
142
	/// Counts parachain inherent data weights. Use `before` and `after` labels to differentiate
143
	/// between the weight before and after filtering.
144
	pub const PARACHAIN_INHERENT_DATA_WEIGHT: CounterVecDefinition = CounterVecDefinition {
145
		name: "polkadot_parachain_inherent_data_weight",
146
		description: "Inherent data weight before and after filtering",
147
		labels: &["when"],
148
	};
149

            
150
	/// Counts the number of bitfields processed in `process_inherent_data`.
151
	pub const PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED: CounterDefinition = CounterDefinition {
152
		name: "polkadot_parachain_inherent_data_bitfields_processed",
153
		description: "Counts the number of bitfields processed in `process_inherent_data`.",
154
	};
155

            
156
	/// Counts the `total`, `sanitized` and `included` number of parachain block candidates
157
	/// in `process_inherent_data`.
158
	pub const PARACHAIN_INHERENT_DATA_CANDIDATES_PROCESSED: CounterVecDefinition =
159
		CounterVecDefinition {
160
			name: "polkadot_parachain_inherent_data_candidates_processed",
161
			description:
162
				"Counts the number of parachain block candidates processed in `process_inherent_data`.",
163
			labels: &["category"],
164
		};
165

            
166
	/// Counts the number of `imported`, `current` and `concluded_invalid` dispute statements sets
167
	/// processed in `process_inherent_data`. The `current` label refers to the disputes statement
168
	/// sets of the current session.
169
	pub const PARACHAIN_INHERENT_DATA_DISPUTE_SETS_PROCESSED: CounterVecDefinition =
170
		CounterVecDefinition {
171
			name: "polkadot_parachain_inherent_data_dispute_sets_processed",
172
			description:
173
				"Counts the number of dispute statements sets processed in `process_inherent_data`.",
174
			labels: &["category"],
175
		};
176

            
177
	/// Counts the number of `valid` and `invalid` bitfields signature checked in
178
	/// `process_inherent_data`.
179
	pub const PARACHAIN_CREATE_INHERENT_BITFIELDS_SIGNATURE_CHECKS: CounterVecDefinition =
180
		CounterVecDefinition {
181
			name: "polkadot_parachain_create_inherent_bitfields_signature_checks",
182
			description:
183
				"Counts the number of bitfields signature checked in `process_inherent_data`.",
184
			labels: &["validity"],
185
		};
186

            
187
	/// Measures how much time does it take to verify a single validator signature of a dispute
188
	/// statement
189
	pub const PARACHAIN_VERIFY_DISPUTE_SIGNATURE: HistogramDefinition =
190
		HistogramDefinition {
191
			name: "polkadot_parachain_verify_dispute_signature",
192
			description: "How much time does it take to verify a single validator signature of a dispute statement, in seconds",
193
			buckets: &[0.0, 0.00005, 0.00006, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.3, 0.5, 1.0],
194
	};
195
}