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
use std::io::{BufRead, BufReader, Read}; #[derive(Default, Debug, PartialEq)] pub struct Disk { pub name: String, pub reads_completed: u64, pub writes_completed: u64, } impl Disk { pub fn get() -> std::io::Result<Vec<Disk>> { let file = std::fs::File::open("/proc/diskstats")?; Self::collect_disk_stats(file) } fn collect_disk_stats<R: Read>(buf: R) -> std::io::Result<Vec<Disk>> { let reader = BufReader::new(buf); let mut disks: Vec<Disk> = vec![]; for line in reader.lines() { if line.is_err() { unimplemented!() } let line = line.unwrap(); let fields: Vec<_> = line.split_ascii_whitespace().collect(); if fields.len() < 14 { continue; } let name = fields[2].to_owned(); let reads_completed = fields[3].parse::<u64>().unwrap(); let writes_completed = fields[7].parse::<u64>().unwrap(); disks.push(Disk { name, reads_completed, writes_completed, }) } Ok(disks) } } #[test] fn test_collect_disk_stats() { let buf = " 202 1 xvda1 750193 3037 28116978 368712 16600606 7233846 424712632 23987908 0 2355636 24345740 202 2 xvda2 1641 9310 87552 1252 6365 3717 80664 24192 0 15040 25428 7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 7 1 loop1 0 0 0 0 0 0 0 0 0 0 0 253 0 dm-0 46095806 0 549095028 2243928 7192424 0 305024576 12521088 0 2728444 14782668 253 628 dm-628 3198 0 75410 1360 30802835 0 3942653176 1334317408 0 70948 1358596768 253 2 dm-2 2022 0 42250 488 30822403 0 3942809696 1364721232 0 93348 1382989868 ".as_bytes(); let expected = vec![ Disk { name: "xvda1".to_owned(), reads_completed: 750193, writes_completed: 16600606, }, Disk { name: "xvda2".to_owned(), reads_completed: 1641, writes_completed: 6365, }, Disk { name: "loop0".to_owned(), reads_completed: 0, writes_completed: 0, }, Disk { name: "loop1".to_owned(), reads_completed: 0, writes_completed: 0, }, Disk { name: "dm-0".to_owned(), reads_completed: 46095806, writes_completed: 7192424, }, Disk { name: "dm-628".to_owned(), reads_completed: 3198, writes_completed: 30802835, }, Disk { name: "dm-2".to_owned(), reads_completed: 2022, writes_completed: 30822403, }, ]; let r = Disk::collect_disk_stats(buf); assert!(r.is_ok()); assert_eq!(r.unwrap(), expected); }