Skip to content

Cloverhound/worker_monitoring

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WorkerMonitoring

A gem for monitoring Sidekiq worker executions with run tracking, success/failure metrics, metadata capture, and optional tenant scoping.

Features

  • Track individual worker executions (runs) with timing, status, and metadata
  • Maintain summary statistics per worker (total runs, success/failure counts)
  • Optional tenant/organization scoping for multi-tenant applications
  • Configurable table names and logging
  • Rails generators for easy setup

Installation

Add this line to your application's Gemfile:

gem "worker_monitoring", path: "../worker_monitoring"
# Or for git-based installation:
# gem "worker_monitoring", git: "https://github.com/Cloverhound/worker_monitoring"

Then run the install generator:

# Without tenant scoping
rails generate worker_monitoring:install

# With tenant scoping
rails generate worker_monitoring:install --tenant-class=Organization --tenant-foreign-key=organization_id

Run migrations:

rails db:migrate

Configuration

Configure the gem in config/initializers/worker_monitoring.rb:

WorkerMonitoring.configure do |config|
  # Tenant/organization scoping
  config.tenant_class = "Organization"      # Set to nil to disable
  config.tenant_foreign_key = :organization_id

  # Table names
  config.worker_table_name = :monitored_workers
  config.run_table_name = :monitored_worker_runs

  # Logger
  config.logger = Rails.logger

  # Custom log context formatter
  config.log_context_formatter = ->(tenant) { " - #{tenant.name} (#{tenant.id})" }
end

Usage

With Tenant Scoping

For workers that operate on a specific tenant/organization:

class SyncUsersWorker
  include Sidekiq::Worker
  include WorkerMonitoring::TenantMonitoring

  def perform(organization_id)
    with_tenant_monitoring("Sync Users", organization_id) do |organization, context|
      # Your work here...
      users = sync_users(organization)

      # Add metadata to the run
      context[:run_metadata][:users_synced] = users.count
      context[:run_metadata][:api_calls] = 5
    end
  end
end

Without Tenant Scoping (Global Workers)

For workers that don't belong to a specific tenant:

class CleanupWorker
  include Sidekiq::Worker
  include WorkerMonitoring::Monitorable

  def perform
    context = init_monitoring("Cleanup Old Records", nil)

    begin
      # Your work here...
      deleted_count = cleanup_records

      context[:run_metadata][:records_deleted] = deleted_count
      complete_monitoring(context, WorkerMonitoring::MonitoredWorkerRun::STATUS_SUCCESS)
    rescue StandardError => e
      complete_monitoring(context, WorkerMonitoring::MonitoredWorkerRun::STATUS_FAILED, error: e)
      raise
    ensure
      finalize_monitoring(context)
    end
  end
end

Models

MonitoredWorker

Tracks a worker type (optionally scoped to a tenant):

worker = WorkerMonitoring::MonitoredWorker.find_by(job: "Sync Users", organization_id: 1)
worker.last_status           # => "success"
worker.last_execution_time   # => 2025-01-05 10:30:00
worker.total_runs_count      # => 42
worker.success_runs_count    # => 40
worker.failed_runs_count     # => 2
worker.success_rate          # => 95.24
worker.average_duration      # => 1234 (ms)
worker.recent_runs(limit: 5) # => [MonitoredWorkerRun, ...]

MonitoredWorkerRun

Tracks individual executions:

run = WorkerMonitoring::MonitoredWorkerRun.last
run.status        # => "success"
run.job           # => "Sync Users" (delegated from monitored_worker)
run.duration_ms   # => 1234
run.metadata      # => { "users_synced" => 100, "api_calls" => 5 }
run.error_context # => nil (or { "message" => "...", "class" => "...", "backtrace" => [...] })

Status Constants

WorkerMonitoring::MonitoredWorkerRun::STATUS_SUCCESS  # => "success"
WorkerMonitoring::MonitoredWorkerRun::STATUS_FAILED   # => "failed"
WorkerMonitoring::MonitoredWorkerRun::STATUS_SKIPPED  # => "skipped"
WorkerMonitoring::MonitoredWorkerRun::STATUS_RUNNING  # => "running"

Development

After checking out the repo, run bin/setup to install dependencies.

License

The gem is available as open source under the terms of your license.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published