Skip to main content

main

Attribute Macro main 

Source
#[main]
Expand description

Instrument an async main function with dial9 telemetry.

This macro is a replacement for #[tokio::main], not a complement — do not use both attributes on the same function. It builds the Tokio runtime internally and wraps the function body in a spawned task so that poll events are recorded by dial9. Without this, code running directly in runtime.block_on(...) is invisible to the telemetry hooks.

To spawn sub-tasks with wake-event tracking from anywhere inside the body, call TelemetryHandle::current() — the handle is installed on every runtime-owned thread by on_thread_start.

§Arguments

  • config — a zero-argument function path or a zero-argument closure returning any value convertible into a TracedRuntime. In practice that means one of:

    • Dial9Config from Dial9Config::builder().build() (strict): any builder validation or writer-I/O failure surfaces from .build() as a Dial9ConfigBuilderError; runtime construction under the macro panics on tokio-builder or telemetry-core I/O.
    • Dial9Config from Dial9Config::builder().build_or_disabled() (lenient): the same Dial9Config type, but validation and writer-I/O failures are logged at error! and downgraded to a disabled config that still preserves your with_tokio configurators.
    • The deprecated positional dial9_tokio_telemetry::config::Dial9Config, kept compatible via a bridge impl.

    Use .enabled(false) on the builder to run without telemetry while keeping your with_tokio configurators.

§Examples

Using a named function:

use dial9_tokio_telemetry::{main, Dial9Config, telemetry::TelemetryHandle};

fn my_config() -> Dial9Config {
    Dial9Config::builder()
        .base_path("/tmp/trace.bin")
        .max_file_size(1024 * 1024)
        .max_total_size(16 * 1024 * 1024)
        .build()
        .expect("config build failed")
}

#[dial9_tokio_telemetry::main(config = my_config)]
async fn main() {
    let handle = TelemetryHandle::current();
    handle
        .spawn(async { /* instrumented sub-task */ })
        .await
        .unwrap();
}

Using an inline closure:

#[dial9_tokio_telemetry::main(config = || {
    Dial9Config::builder()
        .base_path("/tmp/trace.bin")
        .max_file_size(1024 * 1024)
        .max_total_size(16 * 1024 * 1024)
        .build()
        .expect("config build failed")
})]
async fn main() {
    /* ... */
}

Lenient (telemetry is best-effort; falls back to a plain tokio runtime if writer setup fails):

#[dial9_tokio_telemetry::main(config = || {
    Dial9Config::builder()
        .base_path("/tmp/trace.bin")
        .max_file_size(1024 * 1024)
        .max_total_size(16 * 1024 * 1024)
        .build_or_disabled()
})]
async fn main() {
    /* ... */
}

Disabled (no telemetry, plain tokio runtime — useful for toggling dial9 off via a feature flag or env var without removing the macro):

#[dial9_tokio_telemetry::main(config = || {
    Dial9Config::builder()
        .enabled(false)
        .build()
        .expect("config build failed")
})]
async fn main() {
    /* ... */
}