A comprehensive telemetry solution for zkSync CLI applications that combines PostHog analytics and Sentry error tracking while maintaining user privacy and consent.
- ✅ Privacy-focused telemetry collection
- ✅ Opt-in by default
- ✅ Automatic CI environment detection
- ✅ Cross-platform support
- ✅ Configurable data collection
- ✅ Error tracking with context
- ✅ Usage analytics
- ✅ Persistent configuration
Add the library to your Cargo.toml
:
[dependencies]
zksync-telemetry = "0.1.0"
use zksync_telemetry::Telemetry;
use std::error::Error;
fn initialize_telemetry() -> Result<Telemetry, Box<dyn Error>> {
let telemetry = Telemetry::new(
"your-cli-name", // Name of your CLI application
"1.0.0", // Version of your CLI application
"config-name", // Used for config file location and analytics grouping
Some("your-posthog-key".to_string()),// PostHog API key
Some("your-sentry-dsn".to_string()), // Sentry DSN
None, // Use default config path
)?;
Ok(telemetry)
}
app_name
: App or service name reported with every eventapp_version
: App or service version reported with every eventconfig_name
: Used for config file location and analytics groupingposthog_key
: Your PostHog API key (optional)sentry_dsn
: Your Sentry DSN (optional)custom_config_path
: Override default config location (optional)
use std::collections::HashMap;
fn track_cli_usage(telemetry: &Telemetry, command: &str) -> Result<(), Box<dyn Error>> {
let mut properties = HashMap::new();
// Add event properties
properties.insert(
"command".to_string(),
serde_json::Value::String(command.to_string()),
);
properties.insert(
"os".to_string(),
serde_json::Value::String(std::env::consts::OS.to_string()),
);
// Track the event
telemetry.track_event("command_executed", properties)?;
Ok(())
}
fn handle_operation(telemetry: &Telemetry) -> Result<(), Box<dyn Error>> {
match some_risky_operation() {
Ok(result) => Ok(result),
Err(error) => {
// Track the error
telemetry.track_error(&error)?;
Err(error.into())
}
}
}
use zksync_telemetry::{Telemetry, TelemetryConfig};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// Initialize telemetry
let telemetry = Telemetry::new(
"my-cli-app",
"1.0.0",
"config-name",
Some("ph_key".to_string()),
Some("sentry_dsn".to_string()),
None,
)?;
// Use throughout your application
let mut properties = HashMap::new();
properties.insert(
"action".to_string(),
serde_json::Value::String("start".to_string()),
);
// Track application start
telemetry.track_event("app_start", properties)?;
// Your application logic here
match do_something_important() {
Ok(_) => {
let mut success_props = HashMap::new();
success_props.insert(
"status".to_string(),
serde_json::Value::String("success".to_string()),
);
telemetry.track_event("operation_complete", success_props)?;
}
Err(e) => {
telemetry.track_error(&e)?;
}
}
Ok(())
}
Users can update their telemetry consent:
use zksync_telemetry::TelemetryConfig;
fn update_telemetry_settings(enabled: bool) -> Result<(), Box<dyn Error>> {
let mut config = TelemetryConfig::new(
"my-cli-app",
None, // Use default config path
)?;
config.update_consent(enabled)?;
Ok(())
}
The library provides flexible management of PostHog and Sentry API keys through the TelemetryKeys
structure. Both keys are optional, but telemetry features will be disabled for services without valid keys.
use zksync_telemetry::{Telemetry, TelemetryKeys};
fn main() {
let keys = TelemetryKeys::new()
.expect("Failed to initialize telemetry keys");
let telemetry = Telemetry::new(
"your-app-name",
"1.0.0",
"config-name",
keys.posthog_key,
keys.sentry_dsn,
None,
).expect("Failed to initialize telemetry");
}
The library looks for and validates the following environment variables:
POSTHOG_KEY
: PostHog API key (must start with 'phc_')
SENTRY_DSN
: Sentry DSN (must be a valid Sentry URL)
Example:
# Valid PostHog key starting with 'phc_'
export POSTHOG_KEY="phc_your_actual_posthog_key"
# Valid Sentry DSN URL
export SENTRY_DSN="https://[email protected]/your_project"
./your-application
You can also provide custom keys programmatically:
// Both keys are now optional
let keys = TelemetryKeys::with_keys(
Some("phc_your_posthog_key".to_string()),
Some("https://[email protected]/your_project".to_string()),
).expect("Invalid keys provided");
// Or with only PostHog
let posthog_only = TelemetryKeys::with_keys(
Some("phc_your_posthog_key".to_string()),
None,
).expect("Invalid PostHog key");
The library validates keys before accepting them:
- PostHog keys must start with phc_
- Sentry DSNs must be valid URLs starting with 'http' and containing '@sentry.io'
- Invalid keys will result in an error
- Missing keys will disable corresponding features
- No default keys are provided - valid keys must be supplied
- Keys can be rotated by using environment variables
- No sensitive information is collected or transmitted
- Different keys can be used for different environments (development, staging, production)
- The library will function without keys, but telemetry will be disabled
- Store keys securely using environment variables
- Rotate keys periodically
- Use different keys for different environments
- Monitor key usage through PostHog/Sentry dashboards
- Consider disabling telemetry in development/test environments
- Validate key format before using them
- Unix/Linux:
$XDG_CONFIG_HOME/.<app_name>/telemetry.json
- macOS:
~/Library/Application Support/com.matter-labs.<app_name>/telemetry.json
- Windows:
%APPDATA%\matter-labs\<app_name>\telemetry.json
- Custom location can be specified via
custom_config_path
For example, if your CLI app is named "era-test-node":
- macOS:
/Users/<username>/Library/Application Support/com.matter-labs.era-test-node/telemetry.json
- Linux:
~/.config/era-test-node/telemetry.json
- Windows:
C:\Users\<username>\AppData\Roaming\matter-labs\era-test-node\telemetry.json
- Automatically detects CI environments
- Disables telemetry prompts in non-interactive environments
- Supports major CI platforms (GitHub Actions, Jenkins, Travis, etc.)
- Only collects explicitly specified data
- No PII collection
- All data collection is opt-in
- Users can opt-out at any time
- Configuration is stored locally
- No automatic data collection
The library collects:
- Basic usage statistics (commands used)
- Error reports (without sensitive data)
- Platform information (OS, version)
- CLI configuration (non-sensitive settings)
Does NOT collect:
- Personal information
- Sensitive configuration
- Private keys or addresses
- User-specific data
- File paths or system information