Observe your Solid Stack like a pro!
SolidObserver is a production-grade observability solution for Rails 8's Solid Stack. Starting with Solid Queue monitoring in v0.1.0, it provides unified visibility into your background job processing with CLI tools, metrics collection, and distributed tracing support.
Features (v0.1.0)
- 📊 Real-time Queue Status — Monitor jobs across all states (ready, scheduled, claimed, failed)
- 🔍 Job Management CLI — List, inspect, retry, and discard failed jobs
- 💾 Storage Monitoring — Track database size and event counts
- 🔗 Distributed Tracing — Correlate jobs with APM tools (Datadog, Sentry, OpenTelemetry)
- ⚡ High Performance — Buffered writes, configurable sampling, minimal overhead
- 🛡️ Production Ready — Automatic cleanup, size limits, retention policies
Requirements
- Ruby 3.2+
- Rails 8.0+
- Solid Queue (properly configured for all environments)
Note: Ensure Solid Queue is configured with
connects_toin all environments, not just production. See Troubleshooting if you encounter database connection issues.
Installation
Add to your Gemfile:
gem "solid_observer"Run the installer:
bundle install
rails generate solid_observer:installInstall and run migrations:
bin/rails solid_observer:install:migrations
bin/rails db:create
bin/rails db:migrateQuick Start
Check Queue Status
bin/rails solid_observer:statusOutput:
📊 SolidObserver Status
==================================================
🚀 Solid Queue
| Metric | Value |
|-----------|-------|
| Ready | 42 |
| Scheduled | 15 |
| Claimed | 3 |
| Failed | 2 |
| Workers | 4 |
📋 Queue Depths
| Queue | Jobs |
|------------|------|
| default | 38 |
| mailers | 12 |
| critical | 10 |
Manage Jobs
# List jobs (defaults to ready jobs)
bin/rails solid_observer:jobs:list
# List failed jobs
bin/rails "solid_observer:jobs:list[failed]"
# Filter by status, queue, job class, and limit
bin/rails "solid_observer:jobs:list[failed,mailers]"
bin/rails "solid_observer:jobs:list[ready,default,UserNotificationJob,50]"
# Inspect a specific job
bin/rails "solid_observer:jobs:show[JOB_ID]"
# Retry a failed job
bin/rails "solid_observer:jobs:retry[JOB_ID]"
# Discard a failed job
bin/rails "solid_observer:jobs:discard[JOB_ID]"Check Storage
bin/rails solid_observer:storageOutput:
💾 Storage Status
| Component | Size | Events | Usage | Status |
|-----------|---------|--------|-------|--------|
| Queue | 12.5 MB | 45,231 | 1.2% | ✓ |
Configuration:
Retention: 30 days
Max size: 1024.0 MB per database
Warning: 80% threshold
Configuration
After installation, configure SolidObserver in config/initializers/solid_observer.rb:
SolidObserver.configure do |config|
# Enable queue monitoring (default: true)
config.observe_queue = true
# Data Retention
config.event_retention = 30.days # Keep events for 30 days
config.metrics_retention = 90.days # Keep metrics for 90 days
# Database Limits
config.max_db_size = 1.gigabyte # Maximum database size
config.warning_threshold = 0.8 # Warn at 80% capacity
# Performance Tuning
config.buffer_size = 1000 # Buffer before flushing to DB
config.flush_interval = 10.seconds # Flush interval
config.sampling_rate = 1.0 # 1.0 = capture all events
endAPM Integration
Connect SolidObserver with your Application Performance Monitoring tool for distributed tracing:
SolidObserver.configure do |config|
# Datadog APM
config.correlation_id_generator = -> {
Datadog::Tracing.active_trace&.id
}
# Sentry
config.correlation_id_generator = -> {
Sentry.get_current_scope&.transaction&.trace_id
}
# OpenTelemetry
config.correlation_id_generator = -> {
OpenTelemetry::Trace.current_span&.context&.trace_id
}
# Custom implementation
config.correlation_id_generator = -> {
Thread.current[:request_id] || SecureRandom.uuid
}
endWhen configured, all job events will include your correlation ID, allowing you to trace jobs back to the originating request.
CLI Reference
| Command | Description |
|---|---|
solid_observer:status |
Show queue status overview |
solid_observer:jobs:list[status,queue,class,limit] |
List jobs with optional filters |
solid_observer:jobs:show[ID] |
Show job details |
solid_observer:jobs:retry[ID] |
Retry a failed job |
solid_observer:jobs:discard[ID] |
Discard a failed job |
solid_observer:storage |
Show storage statistics |
solid_observer:buffer:flush |
Force flush event buffer to database |
solid_observer:buffer:clear |
Clear buffer without saving |
solid_observer:storage:cleanup |
Run retention-based cleanup |
solid_observer:storage:purge |
Delete ALL SolidObserver data |
Note: These commands manage SolidObserver's storage (event logs, metrics, snapshots) - not Solid Queue's jobs. To manage jobs, use
jobs:discardorjobs:retry.
Jobs List Arguments
Arguments are positional: [status, queue, job_class, limit]
| Position | Description | Example |
|---|---|---|
| 1st | Filter by status |
failed, ready, scheduled
|
| 2nd | Filter by queue name |
default, mailers
|
| 3rd | Filter by job class | UserNotificationJob |
| 4th | Max results (default: 20) | 50 |
# Examples
bin/rails solid_observer:jobs:list # All ready jobs
bin/rails "solid_observer:jobs:list[failed]" # Failed jobs
bin/rails "solid_observer:jobs:list[ready,mailers]" # Ready jobs in mailers queue
bin/rails "solid_observer:jobs:list[failed,,,50]" # 50 failed jobs (skip queue/class)Buffer & Storage Management
# Flush in-memory buffer to database
bin/rails solid_observer:buffer:flush
# Clear buffer without saving (loses pending events!)
bin/rails solid_observer:buffer:clear
# Run cleanup based on retention policy (default: 30 days)
bin/rails solid_observer:storage:cleanup
# Delete ALL SolidObserver data (events + snapshots, interactive confirmation)
bin/rails solid_observer:storage:purgeImportant:
storage:purgedeletes SolidObserver's monitoring data, NOT your Solid Queue jobs. Your queued jobs remain safe.
Database Setup
SolidObserver works with any main application database — PostgreSQL, MySQL, or SQLite.
For its own monitoring data, SolidObserver uses a separate SQLite database. This keeps monitoring isolated from your main app and provides simple file-based storage that requires no additional infrastructure.
# config/database.yml
solid_observer_queue:
<<: *default
adapter: sqlite3 # Always SQLite for SolidObserver storage
database: storage/<%= Rails.env %>_solid_observer_queue.sqlite3Note: Your main app's
primarydatabase can be PostgreSQL, MySQL, or any Rails-supported adapter. Only thesolid_observer_queuedatabase needs to be SQLite.
Roadmap
SolidObserver is actively developed. Here's what's coming:
| Version | Focus | Status |
|---|---|---|
| v0.1.0 | Solid Queue monitoring, CLI tools | ✅ Current |
| v0.2.0 | Solid Cache monitoring | 🔜 Planned |
| v0.3.0 | Solid Cable monitoring | 🔜 Planned |
| v0.4.0 | Cross-component correlation, health scores | 🔜 Planned |
| v0.5.0 | Alerting & notifications | 🔜 Planned |
| v0.6.0 | Web UI dashboard | 🔜 Planned |
| v1.0.0 | Production stable release | 🎯 Goal |
See GitHub Milestones for detailed plans.
Development
# Clone the repository
git clone https://github.com/bart-oz/solid_observer.git
cd solid_observer
# Install dependencies
bin/setup
# Run tests
bundle exec rspec
# Run linter
bundle exec standardrb
# Run code smell detector
bundle exec reekTroubleshooting
"no such table: solid_queue_ready_executions"
This error means Solid Queue isn't configured to use the correct database in your environment.
Solution: Ensure connects_to is configured for all environments, not just production:
# config/environments/development.rb
config.solid_queue.connects_to = { database: { writing: :queue } }
# config/environments/test.rb
config.solid_queue.connects_to = { database: { writing: :queue } }Multi-database setup
SolidObserver works with Rails multi-database configurations. Here's an example with PostgreSQL as your primary database:
development:
primary:
adapter: postgresql
database: myapp_development
# ... PostgreSQL settings
queue:
<<: *default
adapter: sqlite3
database: storage/development_queue.sqlite3
migrations_paths: db/queue_migrate
solid_observer_queue:
adapter: sqlite3
database: storage/development_solid_observer_queue.sqlite3Contributing
Bug reports and pull requests are welcome on GitHub.
Check out issues labeled:
- good first issue — Great for newcomers
- help wanted — We'd love your help
Please follow the code of conduct.
License
The gem is available as open source under the terms of the MIT License.