| Crates.io | ftfrs |
| lib.rs | ftfrs |
| version | 0.1.1 |
| created_at | 2025-04-01 21:25:37.910821+00 |
| updated_at | 2025-04-02 18:34:19.976642+00 |
| description | Read and write Fuchsia Trace Format (FTF) traces with Rust |
| homepage | |
| repository | https://github.com/username/ftfrs |
| max_upload_size | |
| id | 1615613 |
| size | 252,009 |
A Rust library for reading and writing Fuchsia Trace Format (FTF) traces.
⚠️ WARNING ⚠️
This is prototype, in-development software. The API may change significantly between versions and some features are not yet fully implemented. Use in production environments is not recommended at this time.
Add this to your Cargo.toml:
[dependencies]
ftfrs = "0.1.0"
use ftfrs::{Archive, Result};
use std::fs::File;
use std::io::BufReader;
fn main() -> Result<()> {
// Open the trace file
let file = File::open("trace.ftf")?;
let reader = BufReader::new(file);
// Parse the trace archive
let archive = Archive::read(reader)?;
// Process the records in the archive
for (i, record) in archive.records.iter().enumerate() {
println!("Record {}: {:?}", i, record);
}
Ok(())
}
use ftfrs::{
Archive, Record, StringRef, ThreadRef, Result
};
use std::fs::File;
use std::io::BufWriter;
fn main() -> Result<()> {
// Create a new archive
let mut archive = Archive {
records: Vec::new(),
};
// Add magic number record
archive.records.push(Record::create_magic_number());
// Add provider info
archive.records.push(Record::create_provider_info(
1, // provider ID
"my_provider".to_string(),
));
// Add a string record
archive.records.push(Record::create_string(
1, // string index
7, // string length
"example".to_string(),
));
// Add a thread record
archive.records.push(Record::create_thread(
1, // thread index
0x1234, // process KOID
0x5678, // thread KOID
));
// Add an instant event
archive.records.push(Record::create_instant_event(
100_000, // timestamp (100 microseconds)
ThreadRef::Ref(1),
StringRef::Inline("category".to_string()),
StringRef::Inline("started".to_string()),
Vec::new(), // arguments
));
// Add a duration begin event
archive.records.push(Record::create_duration_begin_event(
200_000, // timestamp (200 microseconds)
ThreadRef::Ref(1),
StringRef::Inline("category".to_string()),
StringRef::Inline("process".to_string()),
Vec::new(), // arguments
));
// Add a duration end event
archive.records.push(Record::create_duration_end_event(
300_000, // timestamp (300 microseconds)
ThreadRef::Ref(1),
StringRef::Inline("category".to_string()),
StringRef::Inline("process".to_string()),
Vec::new(), // arguments
));
// Write the archive to a file
let file = File::create("new_trace.ftf")?;
let writer = BufWriter::new(file);
archive.write(writer)?;
println!("Trace file successfully written!");
Ok(())
}
use ftfrs::{Record, StringRef, ThreadRef};
// Create a duration complete event (captures both start and end)
let duration_event = Record::create_duration_complete_event(
100_000, // start timestamp (100 microseconds)
ThreadRef::Ref(1),
StringRef::Inline("category".to_string()),
StringRef::Inline("operation".to_string()),
Vec::new(), // arguments
150_000, // end timestamp (150 microseconds)
);
use ftfrs::{Record, StringRef, ThreadRef, Argument};
// Create a counter event
let counter_event = Record::create_counter_event(
200_000, // timestamp
ThreadRef::Ref(1),
StringRef::Inline("metrics".to_string()),
StringRef::Inline("cpu_usage".to_string()),
Vec::new(), // arguments (would typically contain the counter value)
42, // counter ID
);
When creating events, you can use either inline strings or references to previously defined string records:
// Using a string reference (more efficient for repeated strings)
let event_with_ref = Record::create_instant_event(
300_000,
ThreadRef::Ref(1),
StringRef::Ref(2), // Reference to string record with index 2
StringRef::Ref(3), // Reference to string record with index 3
Vec::new(),
);
// Using an inline string (simpler for one-off strings)
let event_with_inline = Record::create_instant_event(
400_000,
ThreadRef::Ref(1),
StringRef::Inline("category".to_string()), // Inline string
StringRef::Inline("event_name".to_string()), // Inline string
Vec::new(),
);
Events can include arguments of various types to include additional data:
use ftfrs::{Argument, Record, StringRef, ThreadRef};
// Create a vector of arguments of different types
let args = vec![
// Integer arguments
Argument::Int32(StringRef::Inline("count".to_string()), 42),
Argument::UInt64(StringRef::Inline("timestamp_ms".to_string()), 1647359412000),
// Floating point argument
Argument::Float(StringRef::Inline("value".to_string()), 3.14159),
// String argument (can use inline or reference strings for both name and value)
Argument::Str(
StringRef::Inline("message".to_string()),
StringRef::Inline("Operation completed successfully".to_string())
),
// Boolean argument
Argument::Boolean(StringRef::Inline("success".to_string()), true),
// Pointer argument (memory address)
Argument::Pointer(StringRef::Inline("address".to_string()), 0xDEADBEEF),
// Kernel object ID
Argument::KernelObjectId(StringRef::Inline("process_koid".to_string()), 0x1234)
];
// Create an event with arguments
let event_with_args = Record::create_instant_event(
500_000,
ThreadRef::Ref(1),
StringRef::Inline("app".to_string()),
StringRef::Inline("process_data".to_string()),
args
);
Argument names can use string references for efficiency when used repeatedly:
// First, create a string record for the argument name
let string_record = Record::create_string(
10, // string index
5, // string length
"name".to_string()
);
// Then use a reference to this string in arguments
let args = vec![
Argument::Int32(StringRef::Ref(10), 42) // Reference to "name" string
];
The library includes comprehensive benchmarks to measure performance of various operations:
# Run all benchmarks
cargo bench
# Run a specific benchmark group
cargo bench -- string_handling
# Run a specific benchmark
cargo bench -- archive_read/10
Key benchmarking categories:
Read Performance
Write Performance
String Handling Performance
Mixed Workloads
Benchmark results help identify performance characteristics and guide optimization decisions.
The repository includes an example tool that demonstrates reading and writing trace files.
# Create a sample trace file
cargo run --example trace_tool write [output_file.ftf]
# Read and display a trace file
cargo run --example trace_tool read <trace_file.ftf>
The example tool:
The following items are planned for future development:
Contributions are welcome! Feel free to open issues or submit pull requests.
This project is licensed under the MIT License.