errsight 0.1.1

Rust client for ErrSight error tracking — captures panics, errors, and log/tracing events and ships them to the ErrSight API from a background thread.
Documentation
//! Minimal end-to-end usage.
//!
//! Run with a real key to actually deliver:
//!     ERRSIGHT_API_KEY=elp_... cargo run --example basic
//! Without a key the client is a no-op (capture calls return `None`).

use errsight::{Breadcrumb, Config, Level, User};

fn main() {
    // The guard flushes and closes on drop — keep it bound for the whole run.
    let _guard = errsight::init(
        Config::builder()
            .environment("development")
            .release(env!("CARGO_PKG_VERSION"))
            .min_level(Level::Info)
            .debug(true) // print internal diagnostics to stderr
            .build(),
    );

    // Process-wide context.
    errsight::configure_scope(|scope| {
        scope.set_tag("example", "basic");
        scope.set_user(User::new().id("demo-user").email("demo@example.com"));
    });

    errsight::add_breadcrumb(Breadcrumb::new("lifecycle", "application started"));

    // A plain message.
    errsight::capture_message("hello from errsight-rust", Level::Info);

    // An error with a cause chain + backtrace.
    if let Err(err) = do_risky_thing() {
        errsight::capture_error(&err);
        eprintln!("captured error: {err}");
    }

    // Per-block scope isolation.
    errsight::with_scope(|| {
        errsight::configure_scope(|s| {
            s.set_tag("phase", "checkout");
        });
        errsight::capture_message("checkout failed", Level::Error);
    });

    // Drain before exit (the guard would do this anyway).
    errsight::flush(None);
}

#[derive(Debug)]
struct DiskError(String);
impl std::fmt::Display for DiskError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "disk error: {}", self.0)
    }
}
impl std::error::Error for DiskError {}

fn do_risky_thing() -> Result<(), DiskError> {
    Err(DiskError("device is on fire".to_string()))
}