timetrace 0.2.2

Lightweight Rust profiling library with RAII and Chrome/Perfetto trace support
Documentation
#[cfg(feature = "macros")]
pub use timetrace_macros::{profile_function, profile_session, profile_session_limited};

mod backends;
pub mod profile_result;
pub mod profiler;
pub mod profiler_timer;
pub use profiler_timer::ProfilerTimer;

pub use backends::base::TracingBackend;

#[cfg(all(feature = "tracy", feature = "json"))]
compile_error!("features 'tracy' and 'json' are mutually exclusive");

/**
# Timetrace

A lightweight Rust profiling library inspired by Hazel and Tracy-style instrumentation.

Generates JSON traces compatible with Chrome Tracing and Perfetto.
and supports tracy.


## Features

- RAII profiling (scope-based)
- Function attribute macro: `#[profile_function]`
- Session management: `#[profile_session]`
- Frame indexing in trace (`args.frame`)
- Minimal overhead
- Thread-aware (thread id included)


## Example

```rust
use timetrace::{profile_function, profile_session};

#[profile_session("Example", "trace.json")]
fn main() {
    work();
}

#[profile_function]
fn work() {
    let mut sum = 0.0;

    for i in 0..1_000_000 {
        sum += (i as f64).cos();
    }

    println!("{sum}");
}
```


## Run

```bash
cargo run -p timetrace_example
```


## View Trace

Open in:

- https://ui.perfetto.dev
- Only in Google Chrome: chrome://tracing


## Output Example
```json
{
  "name": "work",
  "cat": "function",
  "ph": "X",
  "ts": 123456789,
  "dur": 23000,
  "pid": 0,
  "tid": 12345,
  "args": {
    "frame": 0
  }
}
```
(Actual output is written as a single line JSON)


## Cargo Features

Enable macros:

```toml
timetrace = { path = "...", features = ["json"] }
```
(macros are enabled by default)

Disable macros:
```toml
timetrace = { path = "...", features = ["json"], default-features = false }
```
*/

#[macro_export]
macro_rules! profile_begin_session {
    ($name:expr, $filepath:expr) => {
        use $crate::TracingBackend;
        $crate::profiler::Profiler::get()
            .lock()
            .begin_session($name, $filepath);
    };
}

#[macro_export]
macro_rules! profile_begin_session_limited {
    ($name:expr, $path:expr, $frames:expr, $ms:expr) => {
        use $crate::TracingBackend;
        $crate::profiler::Profiler::get()
            .lock()
            .begin_session_limited($name, $path, $frames, $ms);
    };
}

#[macro_export]
macro_rules! profile_end_session {
    () => {
        use $crate::TracingBackend;
        $crate::profiler::Profiler::get()
            .lock()
            .end_session()
            .unwrap();
    };
}

#[macro_export]
macro_rules! profile_scope {
    ($name:expr) => {
        use $crate::TracingBackend;
        let _timer = $crate::profiler_timer::ProfilerTimer::new($name);
    };
}

#[macro_export]
macro_rules! profile_function_scope {
    () => {
        __profile_function!(module_path!())
    };
}

#[cfg(feature = "tracy")]
#[macro_export]
macro_rules! __profile_function {
    ($name:literal) => {
        let _timetrace_span = tracy_client::span!($name);
    };
}

#[cfg(not(feature = "tracy"))]
#[macro_export]
macro_rules! __profile_function {
    ($name:literal) => {
        use $crate::TracingBackend;
        let _timetrace_timer = $crate::profiler_timer::ProfilerTimer::new($name);
    };
}

#[macro_export]
macro_rules! profile_new_frame {
    () => {
        use $crate::TracingBackend;
        $crate::profiler::Profiler::get().lock().new_frame();
    };
}
#[macro_export]
macro_rules! profile_update {
    ($name:expr, $value:expr) => {
        use $crate::TracingBackend;
        profile_new_frame!();
    };
}