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
|
use std::collections::HashMap;
use linux_perf_data::{PerfFileReader, PerfFileRecord};
fn main() {
let path = std::env::args()
.nth(1)
.expect("Usage: perfdatainfo <perf.data>");
let file = std::fs::File::open(path).unwrap();
let reader = std::io::BufReader::new(file);
let PerfFileReader {
mut perf_file,
mut record_iter,
} = match PerfFileReader::parse_file(reader) {
Ok(reader) => reader,
Err(e) => {
println!("ERROR when creating PerfFileReader: {:?}", e);
return;
}
};
// Print the feature sections.
let features = perf_file.features();
let features: String = features
.iter()
.map(|f| format!("{f}"))
.collect::<Vec<_>>()
.join(", ");
println!("Features: {features}");
println!();
if let Ok(Some(simpleperf_file_symbols)) = perf_file.simpleperf_symbol_tables() {
println!("Simpleperf symbol tables for the following files:");
for f in &simpleperf_file_symbols {
println!(" - {}", f.path);
}
println!();
}
let mut event_record_map = HashMap::new();
let mut user_record_map = HashMap::new();
while let Some(record) = record_iter.next_record(&mut perf_file).unwrap() {
match record {
PerfFileRecord::EventRecord { attr_index, record } => {
let record_type = record.record_type;
*event_record_map
.entry(attr_index)
.or_insert_with(HashMap::new)
.entry(record_type)
.or_insert(0) += 1;
match record.parse() {
Ok(_parsed_record) => {
// println!(
// "{:?} for event {}: {:?}",
// record_type, attr_index, parsed_record
// );
}
Err(e) => {
println!(
"ERROR when parsing {:?} for event {}: {:?}",
record_type, attr_index, e
);
}
}
}
PerfFileRecord::UserRecord(record) => {
let record_type = record.record_type;
*user_record_map.entry(record_type).or_insert(0) += 1;
match record.parse() {
Ok(_parsed_record) => {
// println!("{:?}: {:?}", record_type, parsed_record);
}
Err(e) => {
println!("ERROR when parsing {:?}: {:?}", record_type, e);
}
}
}
}
}
let mut event_record_map = event_record_map
.into_iter()
.map(|(attr_index, histogram)| {
let sum = histogram.values().sum::<u64>();
(attr_index, histogram, sum)
})
.collect::<Vec<_>>();
event_record_map.sort_by_key(|(_attr_index, _histogram, sum)| -(*sum as i64));
let sum = event_record_map
.iter()
.map(|(_attr_index, _histogram, sum)| sum)
.sum::<u64>();
println!("Event records: {sum} records");
println!();
for (attr_index, record_counts, sum) in event_record_map {
let mut record_counts = record_counts.into_iter().collect::<Vec<_>>();
record_counts.sort_by_key(|(_record_type, count)| -(*count as i64));
println!(
" event {} ({}): {} records",
attr_index,
perf_file.event_attributes()[attr_index]
.name()
.unwrap_or("<no event name found>"),
sum
);
for (record_type, count) in record_counts {
println!(" {:?}: {}", record_type, count);
}
println!();
}
let mut user_record_counts = user_record_map.into_iter().collect::<Vec<_>>();
user_record_counts.sort_by_key(|(_record_type, count)| -(*count as i64));
let sum = user_record_counts
.iter()
.map(|(_record_type, count)| count)
.sum::<u64>();
println!("User records: {sum} records");
println!();
for (record_type, count) in user_record_counts {
println!(" {:?}: {}", record_type, count);
}
}
|