A production-ready Rust application for listening to Solana blockchain events via WebSocket with real-time metrics, JSONL persistence, and observability.
This project leverages Rust for:
- Low latency: Zero-cost abstractions and efficient async runtime
- Memory safety: Catch bugs at compile time without garbage collection overhead
- Concurrent performance: Tokio async runtime handles thousands of connections efficiently
- Reliability: Strong typing prevents runtime errors in event processing pipelines
- π Real-time WebSocket connections to Solana RPC
- π Prometheus metrics on
/metricsendpoint - πΎ Append-only JSONL event storage
- π Automatic reconnection with exponential backoff
- π― Dual modes: log subscriptions and account monitoring
- π‘οΈ Graceful shutdown and error recovery
- π¦ Docker Compose setup with Prometheus + Grafana
- Rust 1.83+ (install via rustup)
- Solana mainnet-beta RPC access
git clone <repository-url>
cd solana-event-listener
cp .env.example .env # Edit .env as needed
cargo build --releaseCreate .env file (see .env.example for template):
WS_URL=wss://api.mainnet-beta.solana.com/
MODE=logs
PROGRAM_ID=<your-program-id>
COMMITMENT=finalized
EVENT_LOG_PATH=./events.jsonl
METRICS_ADDR=0.0.0.0:9108
RUST_LOG=infoLogs mode:
cargo run --release -- --mode logs --program-id <PROGRAM_ID>Account mode:
cargo run --release -- --mode account --accounts <PUBKEY1,PUBKEY2>With custom metrics port:
cargo run --release -- --metrics-addr 0.0.0.0:9999Start with Prometheus and Grafana:
# Build and start all services
docker-compose up -d
# View logs
docker-compose logs -f solana-event-listener
# Stop services
docker-compose downAccess dashboards:
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (default:
admin/admin) - Metrics: http://localhost:9108/metrics
curl localhost:9108/metricsSample output:
# HELP sol_events_total Total number of events processed
# TYPE sol_events_total counter
sol_events_total 42
# HELP sol_ws_connected WebSocket connection status (1=connected, 0=disconnected)
# TYPE sol_ws_connected gauge
sol_ws_connected 1
# HELP sol_errors_total Total number of errors encountered
# TYPE sol_errors_total counter
sol_errors_total 0
| Variable | Description | Default | Required |
|---|---|---|---|
WS_URL |
Solana WebSocket endpoint | wss://api.mainnet-beta.solana.com/ |
Yes |
MODE |
Operation mode: logs or account |
logs |
Yes |
PROGRAM_ID |
Program ID for logs mode | - | If MODE=logs |
ACCOUNTS |
Comma-separated addresses for account mode | - | If MODE=account |
COMMITMENT |
Commitment level: processed, confirmed, finalized |
finalized |
No |
EVENT_LOG_PATH |
Path to JSONL event log file | ./events.jsonl |
No |
METRICS_ADDR |
Metrics server bind address | 0.0.0.0:9108 |
No |
RUST_LOG |
Logging level | info |
No |
CLI flags override environment variables.
{"timestamp":"2024-01-15T10:30:45Z","signature":"5VeK...","slot":12345,"program_id":"ComputeBudget111111111111111111111111111111","logs":["Program log: ..."]}{"timestamp":"2024-01-15T10:30:45Z","pubkey":"Address...","slot":12345,"lamports":1000000,"data":"base64..."}Running in logs mode produces output like:
$ cargo run --release -- --mode logs --program-id ComputeBudget111111111111111111111111111111
2024-01-15T10:30:45.123Z INFO Starting Solana Event Listener v0.1.0
2024-01-15T10:30:45.125Z INFO Configuration loaded: mode=logs
2024-01-15T10:30:45.126Z INFO Metrics registry initialized
2024-01-15T10:30:45.127Z INFO Metrics server spawned on 0.0.0.0:9108
2024-01-15T10:30:45.128Z INFO Storage initialized: ./events.jsonl
2024-01-15T10:30:45.129Z INFO Starting logs subscription mode
2024-01-15T10:30:45.130Z INFO Connecting to Solana WebSocket: wss://api.mainnet-beta.solana.com/
2024-01-15T10:30:45.456Z INFO Connected to WebSocket
2024-01-15T10:30:45.457Z INFO Sending subscription request for program: ComputeBudget111111111111111111111111111111
2024-01-15T10:30:45.500Z INFO Subscribed to logs for program: ComputeBudget111111111111111111111111111111
2024-01-15T10:30:46.200Z INFO Event: signature=5VeK..., slot=245000000, program=ComputeBudget111111111111111111111111111111, log_lines=3
2024-01-15T10:30:47.100Z INFO Event: signature=7XmP..., slot=245000001, program=ComputeBudget111111111111111111111111111111, log_lines=2
βββββββββββββββββββββββββββββββββββββββββββ
β Solana Blockchain (Mainnet-Beta) β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β WebSocket JSON-RPC
β (logsSubscribe /
β accountSubscribe)
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Solana Event Listener (Rust) β
β ββββββββββββββββββββββββββββββββββ β
β β WebSocket Client (tokio) β β
β ββββββββββββββ¬ββββββββββββββββββββ β
β β β
β ββββββββββββββΌββββββββββββββββββββ β
β β Event Processing Pipeline β β
β ββββββββββββββ¬ββββββββββββββββββββ β
β β β
β ββββββββββββββ΄ββββββββββββββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββ ββββββββββββββ β
β β JSONL File β β Prometheus β β
β β Storage β β Metrics β β
β ββββββββββββββ ββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββ
cargo testcargo clippy -- -D warningscargo fmt
cargo clippy -- -D warningsMIT
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Run
cargo clippy -- -D warningsandcargo test - Submit a pull request
Issue: "MODE=logs requires PROGRAM_ID to be set"
- Set
PROGRAM_IDin.envor pass--program-idflag
Issue: WebSocket connection fails
- Verify
WS_URLis correct and accessible - Check network connectivity to Solana RPC
- Ensure commitment level is supported
Issue: Metrics not incrementing
- Verify
/metricsendpoint is accessible - Check
RUST_LOG=debugfor detailed logs - Ensure events are being received from Solana