IronTelemetry SDK for Rust
Go to file
David Friedel cc6ec51cdd Add log_message, get_breadcrumbs, and ENABLE_DEBUG_LOGGING features
- Add log_message(level, title, message?, data?) for structured logging with title
- Add get_breadcrumbs() public method to retrieve current breadcrumbs
- Add ENABLE_DEBUG_LOGGING static AtomicBool and set_debug_logging() function
- Update all debug logging to respect the global debug flag

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 11:32:08 +00:00
src Add log_message, get_breadcrumbs, and ENABLE_DEBUG_LOGGING features 2025-12-26 11:32:08 +00:00
.gitignore Implement IronTelemetry Rust SDK 2025-12-25 10:27:55 +00:00
Cargo.toml Implement IronTelemetry Rust SDK 2025-12-25 10:27:55 +00:00
LICENSE Initial commit 2025-12-25 04:55:56 -05:00
README.md Implement IronTelemetry Rust SDK 2025-12-25 10:27:55 +00:00

README.md

IronTelemetry SDK for Rust

Error monitoring and crash reporting SDK for Rust applications. Capture exceptions, track user journeys, and get insights to fix issues faster.

Crates.io Documentation License: MIT

Installation

Add this to your Cargo.toml:

[dependencies]
irontelemetry = "0.1"

For async support:

[dependencies]
irontelemetry = { version = "0.1", features = ["async"] }

Quick Start

Basic Exception Capture

use irontelemetry::{Client, SeverityLevel};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize with your DSN
    let client = Client::new("https://pk_live_xxx@irontelemetry.com")?;

    // Capture a message
    client.capture_message("Application started", SeverityLevel::Info);

    // Capture an exception
    client.capture_exception("RuntimeError", "Something went wrong");

    // Capture from a std::error::Error
    if let Err(e) = do_something() {
        client.capture_error(&*e);
    }

    Ok(())
}

Journey Tracking

Track user journeys to understand the context of errors:

use irontelemetry::{Client, BreadcrumbCategory, create_journey_manager};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("https://pk_live_xxx@irontelemetry.com")?;
    let journey_manager = create_journey_manager(&client);

    // Start a journey
    let mut journey = journey_manager.start_journey("Checkout Flow");
    journey.set_user("user-123", Some("user@example.com"), Some("John Doe"));

    // Track steps with automatic error handling
    let result = journey.run_step("Validate Cart", BreadcrumbCategory::Business, || {
        validate_cart()
    });

    if let Err(e) = result {
        journey.fail(Some(&e.to_string()));
        client.capture_exception("ValidationError", &e.to_string());
        return Err(e.into());
    }

    let result = journey.run_step("Process Payment", BreadcrumbCategory::Business, || {
        process_payment()
    });

    if let Err(e) = result {
        journey.fail(Some(&e.to_string()));
        client.capture_exception("PaymentError", &e.to_string());
        return Err(e.into());
    }

    journey.complete();
    Ok(())
}

Or track steps manually:

let mut journey = journey_manager.start_journey("Checkout Flow");

let mut step = journey.start_step("Validate Cart", BreadcrumbCategory::Business);
step.set_data("cart_items", json!(5));

match validate_cart() {
    Ok(_) => step.complete(),
    Err(e) => {
        step.fail(Some(&e.to_string()));
        journey.fail(Some(&e.to_string()));
        return Err(e.into());
    }
}

journey.complete();

Configuration

use irontelemetry::{Client, TelemetryOptions};

let options = TelemetryOptions::new("https://pk_live_xxx@irontelemetry.com")
    .environment("production")
    .app_version("1.2.3")
    .sample_rate(1.0)  // 100% of events
    .debug(false)
    .before_send(|event| {
        // Filter or modify events
        if event.message.as_ref().map(|m| m.contains("expected")).unwrap_or(false) {
            return None;  // Drop the event
        }
        Some(event)
    });

let client = Client::with_options(options)?;

Configuration Options

Option Type Default Description
dsn String required Your Data Source Name
environment String "production" Environment name
app_version String "0.0.0" Application version
sample_rate f64 1.0 Sample rate (0.0 to 1.0)
max_breadcrumbs usize 100 Max breadcrumbs to keep
debug bool false Enable debug logging
before_send Fn None Hook to filter/modify events
enable_offline_queue bool true Enable offline queue
max_offline_queue_size usize 500 Max offline queue size

Features

  • Automatic Stack Traces: Full stack traces captured with exceptions
  • Journey Tracking: Track user flows and correlate errors with context
  • Breadcrumbs: Leave a trail of events leading up to an error
  • User Context: Associate errors with specific users
  • Tags & Extras: Add custom metadata to your events
  • Thread-Safe: All operations are safe for concurrent use with Arc and RwLock
  • Zero-Copy Where Possible: Efficient memory usage with borrowed data

Breadcrumbs

use irontelemetry::{BreadcrumbCategory, SeverityLevel};
use std::collections::HashMap;
use serde_json::json;

// Add simple breadcrumbs
client.add_breadcrumb("User clicked checkout button", BreadcrumbCategory::Ui);
client.add_breadcrumb("Payment API called", BreadcrumbCategory::Http);

// With level
client.add_breadcrumb_with_level(
    "User logged in",
    BreadcrumbCategory::Auth,
    SeverityLevel::Info,
);

// With data
let mut data = HashMap::new();
data.insert("url".to_string(), json!("/api/checkout"));
data.insert("statusCode".to_string(), json!(200));
data.insert("duration".to_string(), json!(150));

client.add_breadcrumb_with_data(
    "API request completed",
    BreadcrumbCategory::Http,
    SeverityLevel::Info,
    data,
);

Breadcrumb Categories

BreadcrumbCategory::Ui           // User interface interactions
BreadcrumbCategory::Http         // HTTP requests
BreadcrumbCategory::Navigation   // Page/route navigation
BreadcrumbCategory::Console      // Console output
BreadcrumbCategory::Auth         // Authentication events
BreadcrumbCategory::Business     // Business logic events
BreadcrumbCategory::Notification // Notification events
BreadcrumbCategory::Custom       // Custom events

Severity Levels

SeverityLevel::Debug
SeverityLevel::Info
SeverityLevel::Warning
SeverityLevel::Error
SeverityLevel::Fatal

User Context

use irontelemetry::User;
use serde_json::json;
use std::collections::HashMap;

// Simple user ID
client.set_user_by_id("user-123");

// With email
client.set_user_with_email("user-123", "user@example.com");

// Full user object
let mut data = HashMap::new();
data.insert("plan".to_string(), json!("premium"));

client.set_user(User::new("user-123")
    .with_email("user@example.com")
    .with_name("John Doe")
    .with_data(data));

Tags and Extra Data

use serde_json::json;
use std::collections::HashMap;

// Set individual tags
client.set_tag("release", "v1.2.3");
client.set_tag("server", "prod-1");

// Set multiple tags
let mut tags = HashMap::new();
tags.insert("release".to_string(), "v1.2.3".to_string());
tags.insert("server".to_string(), "prod-1".to_string());
client.set_tags(tags);

// Set extra data
client.set_extra("request_id", json!("abc-123"));

let mut extras = HashMap::new();
extras.insert("request_id".to_string(), json!("abc-123"));
extras.insert("user_agent".to_string(), json!("Mozilla/5.0..."));
client.set_extras(extras);

Actix-web Integration Example

use actix_web::{web, App, HttpServer, HttpResponse};
use irontelemetry::{Client, BreadcrumbCategory};
use std::sync::Arc;

struct AppState {
    telemetry: Arc<Client>,
}

async fn handler(data: web::Data<AppState>) -> HttpResponse {
    data.telemetry.add_breadcrumb("Handler called", BreadcrumbCategory::Http);

    // Your logic here

    HttpResponse::Ok().body("Hello")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let client = Client::new("https://pk_live_xxx@irontelemetry.com")
        .expect("Failed to create client");

    let app_state = web::Data::new(AppState {
        telemetry: client,
    });

    HttpServer::new(move || {
        App::new()
            .app_data(app_state.clone())
            .route("/", web::get().to(handler))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Requirements

  • Rust 1.70+
  • reqwest (HTTP client)
  • serde/serde_json (serialization)
  • chrono (timestamps)
  • uuid (event IDs)

License

MIT License - see LICENSE for details.