| Crates.io | hemera |
| lib.rs | hemera |
| version | 0.1.0 |
| created_at | 2025-11-11 16:33:20.048888+00 |
| updated_at | 2025-11-11 16:33:20.048888+00 |
| description | Inevitable timing for Rust functions—measure execution with divine precision. |
| homepage | |
| repository | https://github.com/kunalsinghdadhwal/hemera |
| max_upload_size | |
| id | 1927536 |
| size | 48,824 |
Inevitable timing for Rust functions—measure execution with divine precision.
Hemera is a lightweight, zero-overhead procedural macro for measuring function execution time in Rust. Named after the Greek primordial goddess of the day, Hemera brings clarity and insight to your code's performance characteristics.
println! and eprintln!tracing ecosystem#[measure_time] to any functionAdd Hemera to your Cargo.toml:
cargo add hemera
Or manually:
[dependencies]
hemera = "0.1"
For tracing integration:
[dependencies]
hemera = { version = "0.1", features = ["tracing"] }
use hemera::measure_time;
#[measure_time]
fn calculate_fibonacci(n: u32) -> u32 {
if n <= 1 {
n
} else {
calculate_fibonacci(n - 1) + calculate_fibonacci(n - 2)
}
}
fn main() {
let result = calculate_fibonacci(10);
// Output: [TIMING] Function 'calculate_fibonacci' executed in 23.456µs
}
use hemera::measure_time;
#[measure_time]
async fn fetch_data() -> Result<String, Box<dyn std::error::Error>> {
// Your async code here
Ok("data".to_string())
}
#[tokio::main]
async fn main() {
let data = fetch_data().await.unwrap();
// Output: [TIMING] Function 'fetch_data' executed in 1.234ms
}
#[measure_time(name = "DatabaseQuery")]
fn query_users() -> Vec<User> {
// Your code here
}
// Output: [TIMING] Function 'DatabaseQuery' executed in 45.678ms
Use eprintln! instead of println!:
#[measure_time(level = "debug")]
fn debug_operation() {
// Your code here
}
Only log if execution time exceeds a threshold:
#[measure_time(threshold = "10ms")]
fn maybe_slow_operation() {
// Only logs if this takes more than 10ms
}
Supported units: s (seconds), ms (milliseconds), us (microseconds), ns (nanoseconds)
#[measure_time(name = "CriticalOperation", level = "debug", threshold = "100ms")]
async fn critical_operation() -> Result<(), Error> {
// Your code here
}
Hemera works seamlessly with generic functions:
#[measure_time]
fn process<T: Clone>(value: T) -> T {
value.clone()
}
#[measure_time(name = "GenericAsync")]
async fn async_process<T: Send>(value: T) -> T {
value
}
| Attribute | Type | Default | Description |
|---|---|---|---|
name |
String |
Function name | Custom label for the function in logs |
level |
"info" | "debug" |
"info" |
Log level (info uses println!, debug uses eprintln!) |
threshold |
String |
None | Minimum duration to log (e.g., "10ms", "1s") |
| Feature | Description |
|---|---|
tracing |
Enable integration with the tracing crate |
[dependencies]
hemera = { version = "0.1", features = ["tracing"] }
tracing = "0.1"
When the tracing feature is enabled, Hemera automatically creates tracing spans around your functions.
| Feature | Status |
|---|---|
| Sync functions | Complete |
| Async functions | Complete |
| Threshold filtering | Complete |
| Custom naming | Complete |
| Debug/Info levels | Complete |
| Tracing integration | Complete |
| Block-level measurement | Planned |
| Statistical aggregation | Planned |
| Custom output formatters | Planned |
Check out the examples directory for more usage examples:
basic.rs - Synchronous function examplesasync_example.rs - Async function examplesRun examples with:
cargo run --example basic
cargo run --example async_example
Run benchmarks to measure the macro's overhead:
cargo bench
Benchmark results are saved as HTML reports in target/criterion/. Open target/criterion/report/index.html in your browser to view detailed performance analysis with charts and statistics.
Run the test suite:
# Run all tests
cargo test --all-features
# Run tests without features
cargo test --no-default-features
# Run with tracing feature
cargo test --features tracing
Author: Kunal Singh Dadhwal