9 releases
new 0.1.5 | Mar 9, 2025 |
---|---|
0.1.4 | Sep 28, 2024 |
0.0.4 | Sep 14, 2024 |
0.0.1 | Aug 23, 2024 |
#273 in Rust patterns
Used in sparkles-parser
69KB
1.5K
SLoC
.γ»γγ πβπΈβπππΌπ γ»γγγ»
Performance-focused library for capturing execution flow of your application.
What?
Simply add the instant_event! macro to your code with a string literal and you'll be able to view this event later on a timeline with CPU cycle precision.
How?
Fast. Blazingly fast. π Recording a single event incurs an overhead as low as 10ns and consumes only 3 bytes in the trace buffer (in dense tracing conditions).
Λ ΰΌ βο½‘Λ β§ Λ ΰΌ βο½‘Λ ΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΛ ΰΌ βο½‘Λ β§ Λ ΰΌ βο½‘Λ ΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΰΌ βο½‘Λ β§ Λ ΰΌ
Up to π«Έ100_000_000π«· events per second can be captured in a local environment with no data loss.
ΰΌ βο½‘Λ ΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΰΌ βο½‘Λ β§ Λ ΰΌ βqΛΰΌ βο½‘Λ β§ Λ
β§ Main parts
- sparkles: Ready-to-use library for capturing events and saving them to file in lightweight encoded format.
- sparkles-core: Common functionality for std and no_std (todo) version of sparkles and protocol packets.
- sparkles-macro: instant_event! and range_event_start! macro to encode event name into integer value.
- sparkles-parser: Provides easy to use way of converting recorded trace data to Perfetto format as well as library for realtime parsing.
β§ How to use
- Add sparkles as a dependency to your project
cargo add sparkles
cargo add sparkles-macro
- Add some instant/range events to your code
use std::time::Duration;
use sparkles_macro::{instant_event, range_event_start};
// Refer to sparkles/examples/how_to_use.rs
fn main() {
let finalize_guard = sparkles::init_default();
let g = range_event_start!("main()");
let jh = std::thread::Builder::new().name(String::from("joined thread")).spawn(|| {
for _ in 0..100 {
instant_event!("^-^");
std::thread::sleep(Duration::from_micros(1_000));
}
}).unwrap();
std::thread::Builder::new().name(String::from("detached thread")).spawn(|| {
for _ in 0..30 {
instant_event!("*_*");
std::thread::sleep(Duration::from_micros(1_000));
}
}).unwrap();
for i in 0..1_000 {
instant_event!("β¨β¨β¨");
std::thread::sleep(Duration::from_micros(10));
}
jh.join().unwrap();
}
- Run your code. As it finishes,
trace/*.sprk
is generated. - Run sparkles-parser in the directory with
trace
folder.
cargo run --example interactive
- Go to https://ui.perfetto.dev and drag'n'drop resulting
.perf
file. - Observe the result:
β§ Requirements
π STD support
π x86/x86_64/aarch64 architecture.
OR
π Functioning Instant::now()
β§ Benches
Single event overhead on average x86 machine (Intel i5-12400) is 9ns.
β§ Implementation status
Ready:
π Timestamp provider
π Event name hashing
π Perfetto json format compatibility (replaced with protobuf)
π Ranges (scopes) support
π Configuration support
π Perfetto protobuf format support
π Abstraction over events sending type (UDP/File)
π Automatic timestamp frequency detection
π aarch64 support
π More explicit and recoverable packets with known pattern
π Resistance to data loss during transmission
π UDP real-time reader and parser library API
π Better timestamp speed interpolation in parser
π Sparkles-parser: read and parse in separate threads
TODO:
βοΈ Track changes in structs encoded/decoded by bincode
βοΈ Include git revision into build
βοΈ Option to run without additional bg thread
βοΈ Defmt support
βοΈ Additional attached binary data
βοΈ Option to limit total consumed TLS buffer allocation
βοΈ Module info support: full module path, line of code
βοΈ Async support
βοΈ NO_STD implementation
βοΈ tags / hierarchy of events
βοΈ Viewer app
βοΈ Multi-app sync
βοΈ Global ranges
βοΈ Measurement overhead self-test
Known issues and limitations
β§ Converting timestamp to nanosecond time only have local consistency. Long sessions (day and more) can go out of sync with system clock.
β§ Currently can have only 256 unique event names per thread
β§ Currently up to 256 opened but not closed ranges at a time are supported (mostly enough)
β§ No std support for now
β§ Naive handling for bad network conditions: if at least one packet lost, the whole tracing data packet is dropped.
β§ Cannot specify UDP address to listen on
β§ Proper using of sparkles-macro::range_event_start!("name") gives warning
β§ Timestamp wrap-around is not handled well (not an issue for 64-bit systems)
Crate features
β§ accurate-timestamps-x86 - Enable serialization for x86/x86_64 timestamps. Trade off timestamp accuracy for higher overhead (slightly).
β§ self-tracing - Add global buffer flushing events
qοΎοΎο½₯qο½₯οΎοΎο½‘
οΎγSkyGrel19 β¨
γοΎο½₯qο½₯
Dependencies
~9β16MB
~146K SLoC