#tracing #execution #cpu #events #applications #flow #cycle

sparkles

Capture execution flow of your Rust application with CPU cycle precision!

8 releases

0.1.4 Sep 28, 2024
0.1.3 Sep 22, 2024
0.0.4 Sep 14, 2024
0.0.1 Aug 23, 2024

#664 in Rust patterns

Apache-2.0

52KB
1K SLoC

.γƒ»γ‚œγ‚œ π•Šβ„™π”Έβ„π•‚π•ƒπ”Όπ•Š γƒ»γ‚œγ‚œγƒ»

Performance-focused library for capturing execution flow of application.

img_1.png

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).

˚ ༘ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘Λš ༘ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΛš ༘ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘Λš ༘ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΰΌ˜ β‹†ο½‘Λš ✧ ˚ ༘
Up to 🫸100_000_000🫷 events per second can be captured in a local environment with no data loss.
༘ β‹†ο½‘Λš ༘ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΰΌ˜ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΰΌ˜ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΰΌ˜ β‹†ο½‘Λš ✧ ˚ ༘ β‹†ο½‘ΛšΰΌ˜ β‹†ο½‘Λš ✧ ˚

✧ 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.
  • sparkles-macro: instant_event! and range_event_start! macro to encode event name into integer value.
  • sparkles-parser: This binary will parse tracing data, decode events and save them to file in Perfetto protobuf format.

✧ How to use

  1. Add sparkles as a dependency to your project
cargo add sparkles 
cargo add sparkles-macro
  1. 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();
}
  1. Run your code. As it finishes, trace/*.sprk is generated.
  2. Run sparkles-parser in the directory with trace folder.
cargo run --example interactive
  1. Go to https://ui.perfetto.dev and drag'n'drop resulting .perf file.
  2. Observe the result: img.png

✧ 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

TODO:
βš™οΈ 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
βš™οΈ Capture and transfer loss detection with no corruption to other captured and transmitted data
βš™οΈ Async support
βš™οΈ NO_STD implementation
βš™οΈ tags / hierarchy of events
βš™οΈ Viewer app
βš™οΈ Multi-app sync
βš™οΈ Global ranges
βš™οΈ Measurement overhead self-test

Features

✧ accurate-timestamps-x86 - Enable serialization for x86/x86_64 timestamps
✧ self-tracing - Add global buffer flushing events

q゚゚ο½₯qο½₯゚゚q
οΎŸγ€‚SkyGrel19 ✨
γ€€οΎŸο½₯qο½₯

Dependencies

~1.8–2.9MB
~52K SLoC