Skip to content

Commit

Permalink
added /proc/softirqs
Browse files Browse the repository at this point in the history
Signed-off-by: Navid Yaghoobi <[email protected]>
  • Loading branch information
navidys committed Sep 8, 2024
1 parent d3fed9f commit 90dd3cf
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 0 deletions.
2 changes: 2 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Supported Features
* write_wakeup_threshold
* read_wakeup_threshold

*`/proc/softirqs`

*`/proc/swaps`

*`/sys/class/dmi/id`
Expand Down
13 changes: 13 additions & 0 deletions examples/softirqs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use procsys::softirqs;

fn main() {
let sys_softirqs = softirqs::collect().expect("softirqs information");

match serde_json::to_string_pretty(&sys_softirqs) {
Ok(output) => println!("{}", output),
Err(err) => {
log::error!("{}", err);
std::process::exit(1);
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod process_net_snmp;
pub mod process_net_snmp6;
pub mod process_netstat;
pub mod process_ns;
pub mod softirqs;
pub mod swaps;
pub mod sysfs;
pub mod utils;
137 changes: 137 additions & 0 deletions src/softirqs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use serde::Serialize;

use crate::{error::CollectResult, utils};

/// Softirqs represents the softirq statistics
#[derive(Debug, Serialize, Clone, Default)]
pub struct Softirqs {
pub hi: Vec<u64>,
pub timer: Vec<u64>,
pub net_tx: Vec<u64>,
pub net_rx: Vec<u64>,
pub block: Vec<u64>,
pub irq_poll: Vec<u64>,
pub tasklet: Vec<u64>,
pub sched: Vec<u64>,
pub hr_timer: Vec<u64>,
pub rcu: Vec<u64>,
}

impl Softirqs {
fn new() -> Self {
Default::default()
}
}

/// collects the the softirq statistics
/// # Example
/// ```
/// use procsys::softirqs;
///
/// let sys_softirqs = softirqs::collect().expect("softirqs information");
/// let json_output = serde_json::to_string_pretty(&sys_softirqs).unwrap();
/// println!("{}", json_output);
///
/// ```
pub fn collect() -> CollectResult<Softirqs> {
collect_from("/proc/softirqs")
}

fn collect_from(filename: &str) -> CollectResult<Softirqs> {
let mut proc_softirqs = Softirqs::new();

let irqsdata = utils::read_file_lines(filename)?;

for line in &irqsdata[1..] {
let irqdata = line.to_owned();
let irq_info: Vec<&str> = irqdata
.trim()
.split(' ')
.filter(|s| !s.is_empty())
.collect();

match irq_info[0] {
"HI:" => {
for value in &irq_info[1..] {
proc_softirqs.hi.push(utils::convert_str_to_u64(value)?);
}
}
"TIMER:" => {
for value in &irq_info[1..] {
proc_softirqs.timer.push(utils::convert_str_to_u64(value)?);
}
}
"NET_TX:" => {
for value in &irq_info[1..] {
proc_softirqs.net_tx.push(utils::convert_str_to_u64(value)?);
}
}
"NET_RX:" => {
for value in &irq_info[1..] {
proc_softirqs.net_rx.push(utils::convert_str_to_u64(value)?);
}
}
"BLOCK:" => {
for value in &irq_info[1..] {
proc_softirqs.block.push(utils::convert_str_to_u64(value)?);
}
}
"IRQ_POLL:" => {
for value in &irq_info[1..] {
proc_softirqs
.irq_poll
.push(utils::convert_str_to_u64(value)?);
}
}
"TASKLET:" => {
for value in &irq_info[1..] {
proc_softirqs
.tasklet
.push(utils::convert_str_to_u64(value)?);
}
}
"SCHED:" => {
for value in &irq_info[1..] {
proc_softirqs.sched.push(utils::convert_str_to_u64(value)?);
}
}
"HRTIMER:" => {
for value in &irq_info[1..] {
proc_softirqs
.hr_timer
.push(utils::convert_str_to_u64(value)?);
}
}
"RCU:" => {
for value in &irq_info[1..] {
proc_softirqs.rcu.push(utils::convert_str_to_u64(value)?);
}
}
_ => {}
}
}

Ok(proc_softirqs)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn softirqs_stats() {
let sys_softirqs = collect_from("test_data/fixtures/proc/softirqs")
.expect("collecting softirqs information");

assert_eq!(sys_softirqs.hi, [3, 0]);
assert_eq!(sys_softirqs.timer, [2776180, 247490]);
assert_eq!(sys_softirqs.net_tx, [2419, 772]);
assert_eq!(sys_softirqs.net_rx, [55919, 28694]);
assert_eq!(sys_softirqs.block, [174915, 262755]);
assert_eq!(sys_softirqs.irq_poll, [0, 0]);
assert_eq!(sys_softirqs.tasklet, [209, 75]);
assert_eq!(sys_softirqs.sched, [2278692, 815209]);
assert_eq!(sys_softirqs.hr_timer, [1281, 220]);
assert_eq!(sys_softirqs.rcu, [605871, 532783]);
}
}
7 changes: 7 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,10 @@ pub fn convert_str_to_i64(value: &str) -> CollectResult<i64> {
Err(err) => Err(MetricError::ParseIntError(value.to_string(), err)),
}
}

pub fn convert_str_to_u64(value: &str) -> CollectResult<u64> {
match value.parse::<u64>() {
Ok(c) => Ok(c),
Err(err) => Err(MetricError::ParseIntError(value.to_string(), err)),
}
}
15 changes: 15 additions & 0 deletions test_data/fixtures.ttar
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,21 @@ TCP 1984 93064 1225378 yes 320 yes kernel y y y y y y
NETLINK 1040 16 -1 NI 0 no kernel n n n n n n n n n n n n n n n n n n n
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/softirqs
Lines: 11
CPU0 CPU1
HI: 3 0
TIMER: 2776180 247490
NET_TX: 2419 772
NET_RX: 55919 28694
BLOCK: 174915 262755
IRQ_POLL: 0 0
TASKLET: 209 75
SCHED: 2278692 815209
HRTIMER: 1281 220
RCU: 605871 532783
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/swaps
Lines: 3
Filename Type Size Used Priority
Expand Down

0 comments on commit 90dd3cf

Please sign in to comment.