| Crates.io | telemetry-kit |
| lib.rs | telemetry-kit |
| version | 0.3.0 |
| created_at | 2025-11-19 01:07:49.73697+00 |
| updated_at | 2025-11-26 18:25:22.792751+00 |
| description | Privacy-first, batteries-included telemetry toolkit for Rust applications with OpenTelemetry |
| homepage | https://github.com/ibrahimcesar/telemetry-kit |
| repository | https://github.com/ibrahimcesar/telemetry-kit |
| max_upload_size | |
| id | 1939247 |
| size | 1,184,960 |
Privacy-first usage analytics for Rust open source projects - understand how your CLI tools and libraries are used in the wild
telemetry-kit helps open source maintainers understand how their tools are used in the wild. Add privacy-first telemetry in 3 lines of code. Self-host or use our managed service. Perfect for CLI tools, libraries, and Rust applications.
The following features are fully implemented and tested:
client_ prefix (SHA-256 hashed machine IDs)# 1. Start the server
cd server
docker compose up -d
# 2. Run the end-to-end test
cd ..
cargo run --example e2e_sync_test
See DEPLOYMENT_GUIDE.md for complete setup instructions.
Events are now automatically synced in the background - no manual .sync() calls required!
use telemetry_kit::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Initialize with auto-sync (enabled by default)
let telemetry = TelemetryKit::builder()
.service_name("my-app")?
.with_sync_credentials(org_id, app_id, token, secret)?
.auto_sync(true) // Enable auto-sync (default: true)
.sync_interval(60) // Sync every 60 seconds (default)
.sync_on_shutdown(true) // Sync before exit (default: true)
.build()?;
// Track events - they sync automatically in the background
telemetry.track_command("build", |event| {
event.success(true).duration_ms(1234)
}).await?;
// Graceful shutdown with final sync
telemetry.shutdown().await?;
Ok(())
}
Features:
See examples/auto_sync.rs for a complete example.
Manage telemetry configuration and operations from the command line.
# Install CLI
cargo install telemetry-kit --features cli
# Create a new project with telemetry pre-configured
telemetry-kit new my-app # CLI application
telemetry-kit new my-lib -p lib # Library
telemetry-kit new my-api -p web --with-sync # Web service with sync
# Analyze code for instrumentation opportunities (NEW!)
telemetry-kit analyze # Analyze current directory
telemetry-kit analyze --detailed # Show detailed recommendations with code snippets
telemetry-kit analyze --path src/ # Analyze specific directory
telemetry-kit analyze --format json # Output as JSON
# Interactive setup (for existing projects)
telemetry-kit init
# View statistics
telemetry-kit stats
# Test sync credentials
telemetry-kit test
# Validate configuration
telemetry-kit validate
# Clean local events
telemetry-kit clean
Available Commands:
new - Create new projects with telemetry pre-configuredanalyze - Get smart recommendations on where to add instrumentation (NEW!)init - Interactive project setup with credential configurationtest - Validate sync credentialsstats - View event statistics (total, synced, unsynced)sync - Manually trigger synchronizationvalidate - Validate configurationclean - Clear local event databaseSee CLI.md for complete CLI documentation.
As an open source maintainer, you want to understand:
But current telemetry solutions are:
use telemetry_kit::prelude::*;
#[tokio::main]
#[telemetry_kit::instrumented] // π That's it!
async fn main() {
telemetry_kit::init()
.service_name("my-awesome-cli")
.endpoint("https://telemetry.myapp.com")
.anonymous()
.init();
// Your code here - automatically instrumented!
}
What you get as an OSS maintainer:
Understand Your Users Without Compromising Their Privacy:
// Add to your CLI tool or library
let telemetry = TelemetryKit::builder()
.service_name("my-awesome-cli")?
.service_version(env!("CARGO_PKG_VERSION"))
.prompt_for_consent()? // Ask users first
.build()?;
// Track what matters
telemetry.track_command("build", |event| {
event.success(true).duration_ms(1234)
}).await?;
What You Can Learn:
Build Trust With Your Community:
Showcase Your Impact:
// Literally one line
telemetry_kit::init().auto_configure()?;
telemetry_kit::init()
.anonymous() // Anonymous user IDs
.sanitize_emails() // Hash email addresses
.exclude_env_vars() // Don't capture environment
.gdpr_compliant() // Full GDPR compliance
.consent_prompt() // Ask user on first run
.init();
Enable automatic function instrumentation with the macros feature:
use telemetry_kit::prelude::*;
#[instrument] // Auto-track duration
async fn fetch_data(url: &str) -> Result<Data, Error> {
// Function execution is automatically timed
// Works with both sync and async functions
// Supports Result types for success/failure tracking
let response = reqwest::get(url).await?;
let data = response.json().await?;
Ok(data)
}
Features:
Enable with:
[dependencies]
telemetry-kit = { version = "0.2", features = ["macros"] }
See examples/instrument_macro.rs for a complete example.
Note: Currently the macro measures timing but doesn't send telemetry yet. Full telemetry integration coming soon!
use telemetry_kit::cli::*;
#[derive(Parser)]
#[command(name = "my-cli")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
// Automatically tracks:
// - Which commands are used
// - Command duration
// - Success/failure rates
// - Anonymous usage patterns
telemetry-kit init)| Feature | telemetry-kit | OpenTelemetry | tracing | sentry-rust |
|---|---|---|---|---|
| Setup Complexity | β Low (3 lines) | β οΈ High (50+ lines) | β οΈ Medium | β Low |
| Privacy Built-in | β Yes | β No | β No | β οΈ Partial |
| CLI Optimized | β Yes | β No | β No | β οΈ Partial |
| Auto-instrumentation | β Yes | β No | β No | β οΈ Errors only |
| Self-hostable | β Included | β οΈ Complex | N/A | β Commercial |
| Smart Suggestions | β Yes | β No | β No | β No |
| Offline Support | β Yes | β No | N/A | β οΈ Limited |
| GDPR Compliant | β Built-in | β οΈ Manual | β οΈ Manual | β οΈ Manual |
[dependencies]
telemetry-kit = "0.0.1"
use telemetry_kit::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Initialize with defaults
let _guard = telemetry_kit::init()
.service_name("my-app")
.init()?;
// Your application code
do_work().await?;
Ok(())
}
#[instrument]
async fn do_work() -> Result<()> {
// Automatically tracked!
Ok(())
}
use clap::Parser;
use telemetry_kit::cli::*;
#[derive(Parser)]
#[telemetry_kit::track_commands] // Auto-track all commands!
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
telemetry_kit::init()
.for_cli() // CLI-specific optimizations
.consent_on_first_run() // Ask user permission
.init()?;
match cli.command {
Commands::Build => build().await?,
Commands::Deploy => deploy().await?,
}
Ok(())
}
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Application β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Macros β β Middleware β β Manual β β
β β #[instrument]β β Tracking β β Tracking β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β ββββββββββββββββββββ΄βββββββββββββββββββ β
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β telemetry-kit Core β
β β
β β’ Privacy filters β
β β’ Anonymization β
β β’ Batching β
β β’ Sampling β
ββββββββββββ¬βββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββ
β β β
βββββββββΌβββββββββ βββββββββββΌβββββββββ ββββββββββΌβββββββββ
β OpenTelemetry β β Simple Server β β Custom β
β (OTLP) β β (Self-hosted) β β Backends β
ββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
telemetry-kit is privacy-first by design:
Interactive Consent Prompts (NEW!):
use telemetry_kit::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Show interactive consent dialog on first run
let telemetry = TelemetryKit::builder()
.service_name("my-app")?
.service_version("1.0.0")
.prompt_for_consent()? // Full prompt with privacy details
.build()?;
// Or use minimal one-liner prompt
let telemetry = TelemetryKit::builder()
.service_name("my-app")?
.prompt_minimal()? // Shorter prompt
.build()?;
Ok(())
}
Privacy Configuration:
use telemetry_kit::prelude::*;
use telemetry_kit::privacy::PrivacyConfig;
// Strict privacy mode (GDPR-compliant)
let telemetry = TelemetryKit::builder()
.service_name("my-app")?
.strict_privacy() // Requires consent, sanitizes data, 30-day retention
.build()?;
// Or configure individually
let telemetry = TelemetryKit::builder()
.service_name("my-app")?
.consent_required(true)
.sanitize_paths(true)
.sanitize_emails(true)
.data_retention(90) // Days
.build()?;
Manage Consent via CLI:
telemetry-kit consent grant # Enable telemetry
telemetry-kit consent deny # Disable telemetry
telemetry-kit consent status # Check current status
See examples/interactive_consent.rs and examples/privacy.rs for complete examples.
We welcome contributions! This is a new project and we're building it in the open.
This project is inspired by:
This project is dual-licensed under your choice of:
You may choose either license at your option.
We follow the Rust community standard of dual licensing to give you flexibility:
Both licenses are permissive and allow commercial use, modification, distribution, and private use.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Built with β€οΈ by Ibrahim Cesar and contributors.
Special thanks to:
This project includes the X-Clacks-Overhead: GNU Terry Pratchett header in all HTTP requests to keep the memory of Sir Terry Pratchett alive in the overhead of the internet. Learn more at gnuterrypratchett.com.
"A man is not dead while his name is still spoken." - Going Postal, Terry Pratchett
Status: π§ Early Development - API is unstable and will change
Current Version: 0.0.1 - Placeholder release for crate reservation
First Usable Release: v0.1.0 (Target: Q1 2025)
β Star us on GitHub | π Read the Docs | π¬ Discussions