- 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> |
||
|---|---|---|
| src | ||
| .gitignore | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
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.
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
ArcandRwLock - 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)
Links
License
MIT License - see LICENSE for details.