irontelemetry-rust/README.md

315 lines
8.1 KiB
Markdown

# 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](https://img.shields.io/crates/v/irontelemetry.svg)](https://crates.io/crates/irontelemetry)
[![Documentation](https://docs.rs/irontelemetry/badge.svg)](https://docs.rs/irontelemetry)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
irontelemetry = "0.1"
```
For async support:
```toml
[dependencies]
irontelemetry = { version = "0.1", features = ["async"] }
```
## Quick Start
### Basic Exception Capture
```rust
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:
```rust
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:
```rust
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
```rust
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
```rust
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
```rust
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
```rust
SeverityLevel::Debug
SeverityLevel::Info
SeverityLevel::Warning
SeverityLevel::Error
SeverityLevel::Fatal
```
## User Context
```rust
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
```rust
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
```rust
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
- [Documentation](https://www.irontelemetry.com/docs)
- [Dashboard](https://www.irontelemetry.com)
## License
MIT License - see [LICENSE](LICENSE) for details.