Sidekiq 요청 ID 추적

7568 단어
Sidekiq은 대부분의 Ruby 및 Rails 애플리케이션을 위한 작업 시스템으로 이동합니다. 엄청나게 빠르고, 잘 지원되고, 수천 명이 신뢰하며, 무엇보다 무료입니다! 그러나 작업을 대기열에 추가하게 만든 Railsrequest_id를 추적하는 기본 방법이 포함되었으면 합니다. 작업을 시작한 컨트롤러 작업을 확인하려는 경우에 유용합니다. 하지만 걱정할 필요는 없습니다. Sidekiq에는 Sidekiq 클라이언트 및/또는 서버에서 기능을 구현할 수 있는 미들웨어(Rack과 유사) 개념이 있습니다.

시작하자



Sidekiq 미들웨어를 구현하기 전에 현재 요청을 저장할 장소request_id가 필요합니다. 이 경우에는 Current 모델을 사용합니다. Rails에는 각 요청 전후에 Current에 정의된 속성을 재설정하는 마법이 있습니다. 이는 스레드 격리 데이터를 저장하기에 좋은 장소입니다. 즉, request_id 모델에 Current 속성을 추가해 보겠습니다.

class Current < ActiveSupport::CurrentAttributes
  attribute :request_id
end


모든 요청이 before_action를 저장하도록 ApplicationController에서 request_id를 사용할 수 있습니다.

class ApplicationController < ActionController::Base
  before_action do
    Current.request_id = request.request_id
  end
end


이제 request_id에 대한 전역 액세스 권한이 있으므로 Sidekiq용 클라이언트 및 서버 미들웨어를 생성해야 합니다.

클라이언트 미들웨어



클라이언트 미들웨어는 작업이 Redis로 푸시되기 전에 실행되므로 작업을 수정할 수 있습니다. 이것을 알면 미들웨어는 꽤 쉽습니다.

# You can put this in lib/request_id/sidekiq/client.rb

module RequestId
  module Sidekiq
    class Client
      def call(worker_klass, job, queue, redis_pool)
        # Stash the request_id in the job's metadata
        job['request_id'] = Current.request_id
        yield
      end
    end
  end
end


서버 미들웨어



서버 미들웨어는 작업 실행을 중심으로 실행되므로 작업 실행 전후에 작업을 수행할 수 있습니다. 다시 한 번 call 에 응답하는 클래스입니다.

# You can put this in lib/request_id/sidekiq/server.rb

module RequestId
  module Sidekiq
    class Server
      def call(worker, job, queue)
        Current.request_id = job['request_id']
        yield
      ensure
        Current.reset
      end
    end
  end
end


서버에서 작업의 메타데이터에서 request_id를 가져오고 값을 Current로 설정합니다. ensure를 사용하고 Current.reset를 호출하여 성공 여부에 관계없이 작업이 완료되면 모든 속성을 재설정해야 합니다.

그것을 연결



이제 미들웨어가 있으므로 Sidekiq에 미들웨어를 사용하도록 지시해 보겠습니다.

# config/initializers/sidekiq.rb

require 'lib/request_id/sidekiq/client'
require 'lib/request_id/sidekiq/server'

Sidekiq.configure_server do |config|
  if Sidekiq.server?
    config.server_middleware do |chain|
      chain.add RequestId::Sidekiq::Server
    end
  end
end

Sidekiq.configure_client do |config|
  config.client_middleware do |chain|
    chain.add RequestId::Sidekiq::Client
  end
end


이제 작업에 로그에서 작업을 트리거한 request_id를 포함할 수 있습니다.

class ImportUsersFromCsvWorker
  include Sidekiq::Worker

  def perform(csv)
    # …do stuff
    Rails.logger.info({ message: 'Imported Users', request_id: Current.request_id })
  end
end


요약



작업을 트리거한 작업을 아는 것은 디버깅하는 동안 매우 강력할 수 있습니다. 몇 줄의 코드로 Sidekiq용 미들웨어를 구현하여 작업을 대기열에 추가한 요청의 request_id를 사용할 수 있습니다. 한 단계 더 나아가 Sidekiq의 컨텍스트에 request_id를 추가하고 원하는 경우 기본 로그에 포함할 수도 있습니다.

앱에서 어떤 Sidekiq 미들웨어를 구현했거나 유용하다고 생각했나요?

좋은 웹페이지 즐겨찾기