Sidekiq 로깅

Worker context

로그에서 worker에 대한 더 많은 정보를 얻기 위해, 우리는 ApplicationContext 형식의 메타데이터를 job에 추가합니다. 대부분의 경우, 요청에서 작업을 예약할 때 이미 해당 컨텍스트가 유추되어 예약된 작업에 추가됩니다.

작업이 실행될 때, 해당 작업을 예약할 때 활성화된 컨텍스트가 복원됩니다. 이로 인해 해당 컨텍스트가 실행 중인 작업 내에서 예약된 모든 작업으로 전파됩니다.

이 모든 것은 대부분의 경우에는 작업에 컨텍스트를 추가할 필요가 없다는 것을 의미합니다.

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

대부분의 경우와 마찬가지로 이들을 비활성화하는 데는 완전히 타당한 이유가 있습니다. 이 경우에는 요청에서의 컨텍스트가 올바른 경우일 수 있습니다. 또는 이미 규칙에 포함되지 않은 방식으로 컨텍스트를 지정했을 수 있습니다. 어쨌든, 규칙을 비활성화할 때 사용할 컨텍스트를 가리키는 코드 주석을 남겨두세요.

컨텍스트에 객체를 제공하는 경우, 네임스페이스 및 프로젝트의 경로가 사전로드되었는지 확인하세요. 이 작업은 모든 Routable에 정의된 .with_route 스코프를 사용하여 수행할 수 있습니다.

Cron 작업자

Cron 작업자(include CronjobQueue)에 대해 작업자의 컨텍스트는 자동으로 지워집니다. 심지어 요청에서 이들을 예약하더라도 그렇습니다. 다른 작업자가 cron 작업자에서 예약될 때 잘못된 메타데이터를 피하기 위해 이 작업을 수행합니다.

Cron 작업자 자체는 인스턴스 전체에서 실행되므로 사용자, 네임스페이스, 프로젝트 또는 다른 리소스에 대한 범위가 없습니다. 하지만 종종 컨텍스트가 필요한 다른 작업을 예약합니다.

따라서 작업자 내부의 어딘가에서 다음 중 하나의 방법을 사용하여 컨텍스트를 나타내야 합니다:

  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.

Arguments 로깅

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

기본적으로 로깅되는 인수는 숫자형 인수이며, 다른 유형의 인수는 민감한 정보가 포함될 수 있기 때문에 로깅되지 않습니다. 이를 재정의하려면 숫자형 인수에는 여기에 지정하지 않아도 되지만, 논리적인 인수에 대한 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