vmm/devices/virtio/mem/
metrics.rs

1// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Defines the metrics system for memory devices.
5//!
6//! # Metrics format
7//! The metrics are flushed in JSON when requested by vmm::logger::metrics::METRICS.write().
8//!
9//! ## JSON example with metrics:
10//! ```json
11//!  "memory_hotplug": {
12//!     "activate_fails": "SharedIncMetric",
13//!     "queue_event_fails": "SharedIncMetric",
14//!     "queue_event_count": "SharedIncMetric",
15//!     ...
16//!  }
17//! }
18//! ```
19//! Each `memory` field in the example above is a serializable `VirtioMemDeviceMetrics` structure
20//! collecting metrics such as `activate_fails`, `queue_event_fails` etc. for the memoty hotplug
21//! device.
22//! Since Firecrakcer only supports one virtio-mem device, there is no per device metrics and
23//! `memory_hotplug` represents the aggregate entropy metrics.
24
25use serde::ser::SerializeMap;
26use serde::{Serialize, Serializer};
27
28use crate::logger::{LatencyAggregateMetrics, SharedIncMetric};
29
30/// Stores aggregated virtio-mem metrics
31pub(super) static METRICS: VirtioMemDeviceMetrics = VirtioMemDeviceMetrics::new();
32
33/// Called by METRICS.flush(), this function facilitates serialization of virtio-mem device metrics.
34pub fn flush_metrics<S: Serializer>(serializer: S) -> Result<S::Ok, S::Error> {
35    let mut seq = serializer.serialize_map(Some(1))?;
36    seq.serialize_entry("memory_hotplug", &METRICS)?;
37    seq.end()
38}
39
40#[derive(Debug, Serialize)]
41pub(super) struct VirtioMemDeviceMetrics {
42    /// Number of device activation failures
43    pub activate_fails: SharedIncMetric,
44    /// Number of queue event handling failures
45    pub queue_event_fails: SharedIncMetric,
46    /// Number of queue events handled
47    pub queue_event_count: SharedIncMetric,
48    /// Latency of Plug operations
49    pub plug_agg: LatencyAggregateMetrics,
50    /// Number of Plug operations
51    pub plug_count: SharedIncMetric,
52    /// Number of plugged bytes
53    pub plug_bytes: SharedIncMetric,
54    /// Number of Plug operations failed
55    pub plug_fails: SharedIncMetric,
56    /// Latency of Unplug operations
57    pub unplug_agg: LatencyAggregateMetrics,
58    /// Number of Unplug operations
59    pub unplug_count: SharedIncMetric,
60    /// Number of unplugged bytes
61    pub unplug_bytes: SharedIncMetric,
62    /// Number of Unplug operations failed
63    pub unplug_fails: SharedIncMetric,
64    /// Number of discards failed for an Unplug or UnplugAll operation
65    pub unplug_discard_fails: SharedIncMetric,
66    /// Latency of UnplugAll operations
67    pub unplug_all_agg: LatencyAggregateMetrics,
68    /// Number of UnplugAll operations
69    pub unplug_all_count: SharedIncMetric,
70    /// Number of UnplugAll operations failed
71    pub unplug_all_fails: SharedIncMetric,
72    /// Latency of State operations
73    pub state_agg: LatencyAggregateMetrics,
74    /// Number of State operations
75    pub state_count: SharedIncMetric,
76    /// Number of State operations failed
77    pub state_fails: SharedIncMetric,
78}
79
80impl VirtioMemDeviceMetrics {
81    /// Const default construction.
82    const fn new() -> Self {
83        Self {
84            activate_fails: SharedIncMetric::new(),
85            queue_event_fails: SharedIncMetric::new(),
86            queue_event_count: SharedIncMetric::new(),
87            plug_agg: LatencyAggregateMetrics::new(),
88            plug_count: SharedIncMetric::new(),
89            plug_bytes: SharedIncMetric::new(),
90            plug_fails: SharedIncMetric::new(),
91            unplug_agg: LatencyAggregateMetrics::new(),
92            unplug_count: SharedIncMetric::new(),
93            unplug_bytes: SharedIncMetric::new(),
94            unplug_fails: SharedIncMetric::new(),
95            unplug_discard_fails: SharedIncMetric::new(),
96            unplug_all_agg: LatencyAggregateMetrics::new(),
97            unplug_all_count: SharedIncMetric::new(),
98            unplug_all_fails: SharedIncMetric::new(),
99            state_agg: LatencyAggregateMetrics::new(),
100            state_count: SharedIncMetric::new(),
101            state_fails: SharedIncMetric::new(),
102        }
103    }
104}
105
106#[cfg(test)]
107pub mod tests {
108    use super::*;
109    use crate::logger::IncMetric;
110
111    #[test]
112    fn test_memory_hotplug_metrics() {
113        let mem_metrics: VirtioMemDeviceMetrics = VirtioMemDeviceMetrics::new();
114        mem_metrics.queue_event_count.inc();
115        assert_eq!(mem_metrics.queue_event_count.count(), 1);
116        let _ = serde_json::to_string(&mem_metrics).unwrap();
117    }
118}