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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// src/metrics.rs
#[cfg(feature = "metrics")]
mod metrics_impl {
use once_cell::sync::Lazy;
use prometheus::{
register_histogram_vec, register_int_counter_vec, register_int_gauge_vec, HistogramVec,
IntCounterVec, IntGaugeVec,
};
use prometheus_client::metrics::counter::Counter;
use std::sync::atomic::AtomicU64;
/// Metrics collection and reporting for the bot engine.
///
/// This module provides a simple metrics implementation that can be replaced
/// with a more sophisticated one in production environments.
pub struct Metrics {
/// The histogram for recording the duration of action executions.
pub action_execution_duration: HistogramVec,
/// The counter for recording the total number of actions executed.
pub actions_executed_total: IntCounterVec,
/// The counter for recording error occurrences.
pub error_count: IntCounterVec,
/// The histogram for recording the duration of event processing.
pub event_processing_duration: HistogramVec,
/// The gauge for recording the current size of the event queue.
pub event_queue_size: IntGaugeVec,
/// The counter for recording the total number of events processed.
pub events_processed_total: IntCounterVec,
/// The gauge for recording the current size of the action queue.
pub action_queue_size: IntGaugeVec,
}
impl Metrics {
/// Creates a new metrics instance.
pub fn new() -> Self {
Self {
action_execution_duration: register_histogram_vec!(
"botcore_action_execution_duration_seconds",
"Time taken to execute actions",
&["executor"]
)
.expect("failed to create histogram"),
actions_executed_total: register_int_counter_vec!(
"botcore_actions_executed_total",
"Total number of actions executed",
&["executor"]
)
.expect("failed to create counter"),
error_count: register_int_counter_vec!(
"botcore_errors_total",
"Total number of errors encountered",
&["component", "error_type"]
)
.expect("failed to create counter"),
event_processing_duration: register_histogram_vec!(
"botcore_event_processing_duration_seconds",
"Time taken to process events through strategies",
&["strategy"]
)
.expect("failed to create histogram"),
event_queue_size: register_int_gauge_vec!(
"botcore_event_queue_size",
"Current size of the event queue",
&["collector"]
)
.expect("failed to create gauge"),
events_processed_total: register_int_counter_vec!(
"botcore_events_processed_total",
"Total number of events processed",
&["collector"]
)
.expect("failed to create counter"),
action_queue_size: register_int_gauge_vec!(
"botcore_action_queue_size",
"Current size of the action queue",
&["strategy"]
)
.expect("failed to create gauge"),
}
}
// Methods for recording metrics
/// Records the duration of an action execution.
///
/// # Arguments
///
/// * `executor_label` - The label identifying the executor
/// * `duration` - The duration of the action execution in seconds
pub fn record_action_execution(&self, executor_label: &str, duration: f64) {
self.action_execution_duration
.with_label_values(&[executor_label])
.observe(duration);
}
/// Increments the count of executed actions.
///
/// # Arguments
///
/// * `executor_label` - The label identifying the executor
pub fn inc_actions_executed(&self, executor_label: &str) {
self.actions_executed_total
.with_label_values(&[executor_label])
.inc();
}
/// Records an error occurrence.
///
/// # Arguments
///
/// * `component` - The component where the error occurred
/// * `error_type` - The type of error that occurred
pub fn record_error(&self, component: &str, error_type: &str) {
self.error_count
.with_label_values(&[component, error_type])
.inc();
}
/// Records the duration of event processing.
///
/// # Arguments
///
/// * `strategy_label` - The label identifying the strategy
/// * `duration` - The duration of event processing in seconds
pub fn record_event_processing(&self, strategy_label: &str, duration: f64) {
self.event_processing_duration
.with_label_values(&[strategy_label])
.observe(duration);
}
/// Updates the current size of the event queue.
///
/// # Arguments
///
/// * `collector_label` - The label identifying the collector
/// * `size` - The current size of the queue
pub fn update_event_queue_size(&self, collector_label: &str, size: i64) {
self.event_queue_size
.with_label_values(&[collector_label])
.set(size);
}
/// Increments the count of processed events.
///
/// # Arguments
///
/// * `collector_label` - The label identifying the collector
pub fn inc_events_processed(&self, collector_label: &str) {
self.events_processed_total
.with_label_values(&[collector_label])
.inc();
}
/// Updates the current size of the action queue.
///
/// # Arguments
///
/// * `strategy_label` - The label identifying the strategy
/// * `size` - The current size of the queue
pub fn update_action_queue_size(&self, strategy_label: &str, size: i64) {
self.action_queue_size
.with_label_values(&[strategy_label])
.set(size);
}
}
impl Default for Metrics {
fn default() -> Self {
Self::new()
}
}
/// The global metrics instance used throughout the crate.
///
/// This instance provides access to all Prometheus metrics collectors:
/// - Action execution metrics (duration and count)
/// - Event processing metrics (duration and count)
/// - Queue size metrics (events and actions)
/// - Error tracking metrics
///
/// When the `metrics` feature is enabled, this provides real Prometheus metrics collection.
pub static METRICS: Lazy<Metrics> = Lazy::new(|| Metrics::new());
}
#[cfg(feature = "metrics")]
pub use metrics_impl::*;
////////////////////////////////////////////////////
// When the metrics feature is disabled, provide a stub
#[cfg(not(feature = "metrics"))]
mod metrics_stub {
/// A mock metrics implementation for testing.
///
/// This struct provides no-op implementations of all metrics methods
/// to facilitate testing without requiring a real metrics backend.
pub struct Metrics;
impl Default for Metrics {
fn default() -> Self {
Self::new()
}
}
impl Metrics {
/// Creates a new mock metrics instance.
#[must_use]
pub fn new() -> Self {
Metrics
}
/// Records the duration of an action execution.
///
/// # Arguments
///
/// * `executor_label` - The label identifying the executor
/// * `duration` - The duration of the action execution in seconds
pub fn record_action_execution(&self, _executor_label: &str, _duration: f64) {}
/// Increments the count of executed actions.
///
/// # Arguments
///
/// * `executor_label` - The label identifying the executor
pub fn inc_actions_executed(&self, _executor_label: &str) {}
/// Records an error occurrence.
///
/// # Arguments
///
/// * `component` - The component where the error occurred
/// * `error_type` - The type of error that occurred
pub fn record_error(&self, _component: &str, _error_type: &str) {}
/// Records the duration of event processing.
///
/// # Arguments
///
/// * `strategy_label` - The label identifying the strategy
/// * `duration` - The duration of event processing in seconds
pub fn record_event_processing(&self, _strategy_label: &str, _duration: f64) {}
/// Updates the current size of the event queue.
///
/// # Arguments
///
/// * `collector_label` - The label identifying the collector
/// * `size` - The current size of the queue
pub fn update_event_queue_size(&self, _collector_label: &str, _size: i64) {}
/// Increments the count of processed events.
///
/// # Arguments
///
/// * `collector_label` - The label identifying the collector
pub fn inc_events_processed(&self, _collector_label: &str) {}
/// Updates the current size of the action queue.
///
/// # Arguments
///
/// * `strategy_label` - The label identifying the strategy
/// * `size` - The current size of the queue
pub fn update_action_queue_size(&self, _strategy_label: &str, _size: i64) {}
}
/// The global metrics instance used throughout the crate.
///
/// This is a mock implementation used for testing that provides
/// no-op implementations of all metrics methods.
pub static METRICS: Metrics = Metrics;
}
#[cfg(not(feature = "metrics"))]
pub use metrics_stub::*;