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

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors