Sidekiq 로깅

Worker 컨텍스트

로그에서 워커에 대한 추가 정보를 얻으려면, 우리는 Rails 또는 Grape 요청을 통해 ApplicationContext 형식의 메타데이터를 작업에 추가합니다. 대부분의 경우, 요청에서 작업을 예약할 때 이 컨텍스트는 이미 요청에서 유도되어 예약된 작업에 추가됩니다.

작업이 실행될 때 예약된 작업을 예약할 때 활성화되어 있던 컨텍스트가 복원됩니다. 이로 인해 컨텍스트가 실행 중인 작업 내에서 예약된 어떤 작업으로도 전파됩니다.

이 모든 것은 대부분의 경우에는 작업에 컨텍스트를 추가하기 위해 우리가 아무것도 할 필요가 없음을 의미합니다.

그러나 작업이 예약될 때 컨텍스트가 없거나 예약된 컨텍스트가 올바르지 않을 가능성이 있는 몇 가지 경우가 있습니다. 이러한 경우를 위해 로그 파일에서 잘못된 메타데이터를 감지하고 피하기 위해 우리는 RuboCop 규칙을 추가했습니다.

대부분의 경우에서 우리의 규칙들을 비활성화하는 것에 대한 완전히 타당한 이유가 있습니다. 이 경우에는 요청에서의 컨텍스트가 올바르다는 것일 수도 있습니다. 또는 이미 규칙에 의해 감지되지 않는 방식으로 이미 컨텍스트를 지정한 경우일 수도 있습니다. 여느 케이스에 있어서도 규칙을 비활성화할 때 사용할 컨텍스트를 가리키는 코드 주석을 추가하세요.

컨텍스트에 객체를 제공할 때는 네임스페이스와 프로젝트의 경로를 사전로드해야 합니다. 이는 모든 Routable에 정의된 .with_route 스코프를 사용하여 수행할 수 있습니다.

Cron 워커

워커의 컨텍스트는 크론 작업 대기열 (include CronjobQueue)에 대해 자동으로 지워집니다. 심지어 요청에서도 이들을 예약하는 경우에도 마찬가지로 컨텍스트가 올바르지 않은 다른 작업이 크론 워커에서 예약될 때 잘못된 메타데이터를 피하기 위해 이 작업을 수행합니다.

크론 워커 자체는 인스턴스 전역에서 실행되므로 사용자, 네임스페이스, 프로젝트 또는 컨텍스트에 추가되어야 하는 다른 리소스에 적용되지 않습니다.

그러나 그들은 종종 컨텍스트가 필요한 다른 작업을 예약합니다.

그래서 워커 내 어딘가에 다음 중 하나의 방법을 사용하여 컨텍스트의 표시가 필요합니다:

  1. 작업을 예약하는 코드를 with_context 도우미로 래핑합니다.

      def perform
        deletion_cutoff = Gitlab::CurrentSettings
                            .deletion_adjourned_period.days.ago.to_date
        projects = Project.with_route.with_namespace
                     .aimed_for_deletion(deletion_cutoff)
    
        projects.find_each(batch_size: 100).with_index do |project, index|
          delay = index * INTERVAL
    
          with_context(project: project) do
            AdjournedProjectDeletionWorker.perform_in(delay, project.id)
          end
        end
      end
    
  2. 컨텍스트를 제공하는 일괄 예약 방법을 사용합니다:

      def schedule_projects_in_batch(projects)
        ProjectImportScheduleWorker.bulk_perform_async_with_contexts(
          projects,
          arguments_proc: -> (project) { project.id },
          context_proc: -> (project) { { project: project } }
        )
      end
    

    또는 지연 시간을 사용하여 예약하는 경우:

      diffs.each_batch(of: BATCH_SIZE) do |diffs, index|
        DeleteDiffFilesWorker
          .bulk_perform_in_with_contexts(index *  5.minutes,
                                         diffs,
                                         arguments_proc: -> (diff) { diff.id },
                                         context_proc: -> (diff) { { project: diff.merge_request.target_project } })
      end
    

일괄로 예약된 작업

일괄로 작업을 예약할 때 종종 이러한 작업은 포괄적인 컨텍스트 대신 별도의 컨텍스트를 가져야 합니다.

이러한 경우에는 bulk_perform_asyncbulk_perform_async_with_context 도우미로 대체하고, bulk_perform_in 대신에 bulk_perform_in_with_context를 사용하면 됩니다.

예:

    ProjectImportScheduleWorker.bulk_perform_async_with_contexts(
      projects,
      arguments_proc: -> (project) { project.id },
      context_proc: -> (project) { { project: project } }
    )

첫 번째 인자의 열거형에서 각 객체는 2개의 블록으로 전달됩니다:

  • 작업이 예약되어야 하는 인수 목록을 반환해야 하는 arguments_proc.

  • 작업의 컨텍스트 정보를 포함하는 해시 값을 반환해야 하는 context_proc.

인수 로깅

GitLab 13.6부터 SIDEKIQ_LOG_ARGUMENTS가 비활성화되지 않는 한 Sidekiq 작업 인수는 기본적으로 로그에 기록됩니다.

기본적으로 로그에 기록되는 인수는 숫자 인수뿐이며, 다른 유형의 인수는 민감한 정보를 포함할 수 있기 때문에 그렇습니다. 이를 재정의하려면 작업 내에서 loggable_arguments를 사용하여 로그에 기록할 인수의 색인을 사용하세요. (숫자 인수는 여기에 명시할 필요가 없습니다.)

예를 들면:

class MyWorker
  include ApplicationWorker

  loggable_arguments 1, 3

  # object_id는 숫자이므로 로그에 기록됩니다
  # string_a는 loggable_arguments 호출로 인해 로깅됩니다
  # string_b는 로그에서 필터링됩니다
  # string_c는 loggable_arguments 호출로 인해 로거됩니다
  def perform(object_id, string_a, string_b, string_c)
  end
end