#perf #linux #parser #perf-event #data-file #linux-kernel #file-format

linux-perf-data

A parser for the perf.data format and the jitdump format. These formats are used by the Linux perf tool.

12 releases (breaking)

0.9.0 Mar 4, 2024
0.8.2 Jun 12, 2023
0.8.0 Mar 20, 2023
0.7.0 Dec 8, 2022
0.6.0 Jun 10, 2022

#180 in Parser implementations

Download history 65/week @ 2023-12-18 26/week @ 2023-12-25 22/week @ 2024-01-01 136/week @ 2024-01-08 147/week @ 2024-01-15 114/week @ 2024-01-22 94/week @ 2024-01-29 231/week @ 2024-02-05 285/week @ 2024-02-12 201/week @ 2024-02-19 825/week @ 2024-02-26 853/week @ 2024-03-04 385/week @ 2024-03-11 461/week @ 2024-03-18 315/week @ 2024-03-25 934/week @ 2024-04-01

2,115 downloads per month
Used in 5 crates (2 directly)

MIT/Apache

130KB
2K SLoC

crates.io page docs.rs page

linux-perf-data

A parser for the perf.data file format.

Files of this format consist of a header, a data section, and a few other supplemental sections. The data section contains the main content of the file: a sequence of records.

There are two types of records: event records from the kernel, and "user records" from perf / simpleperf.

This crate also contains parsing code for jitdump files, which are used in conjunction with perf.data files when profiling JIT runtimes.

Example

use linux_perf_data::{AttributeDescription, PerfFileReader, PerfFileRecord};

let file = std::fs::File::open("perf.data")?;
let reader = std::io::BufReader::new(file);
let PerfFileReader { mut perf_file, mut record_iter } = PerfFileReader::parse_file(reader)?;
let event_names: Vec<_> =
    perf_file.event_attributes().iter().filter_map(AttributeDescription::name).collect();
println!("perf events: {}", event_names.join(", "));

while let Some(record) = record_iter.next_record(&mut perf_file)? {
    match record {
        PerfFileRecord::EventRecord { attr_index, record } => {
            let record_type = record.record_type;
            let parsed_record = record.parse()?;
            println!("{:?} for event {}: {:?}", record_type, attr_index, parsed_record);
        }
        PerfFileRecord::UserRecord(record) => {
            let record_type = record.record_type;
            let parsed_record = record.parse()?;
            println!("{:?}: {:?}", record_type, parsed_record);
        }
    }
}

Jitdump example

use linux_perf_data::jitdump::{JitDumpReader, JitDumpRecord};

let file = std::fs::File::open("jit-12345.dump")?;
let mut reader = JitDumpReader::new(file)?;
println!("jitdump header: {:?}", reader.header());

while let Some(raw_record) = reader.next_record()? {
    let timestamp = raw_record.timestamp;
    match raw_record.parse()? {
        JitDumpRecord::CodeLoad(record) => {
            println!("{timestamp:016} LOAD {record:?}");
        }
        JitDumpRecord::CodeMove(record) => {
            println!("{timestamp:016} MOVE {record:?}");
        }
        JitDumpRecord::CodeDebugInfo(record) => {
            println!("{timestamp:016} DEBUG_INFO {record:?}");
        }
        JitDumpRecord::CodeClose => {
            println!("{timestamp:016} CLOSE");
        }
        JitDumpRecord::CodeUnwindingInfo(record) => {
            println!("{timestamp:016} UNWINDING_Info {record:?}");
        }
        JitDumpRecord::Other(record) => {
            println!("{timestamp:016} {} {record:?}", record.record_type.0);
        }
    }
}

License

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~0.9–1.5MB
~31K SLoC