Sidekiqロギング
ワーカーコンテキスト
GitLab 12.8で導入されました。
ワーカーに関する情報をログに残すために、ApplicationContext
](../logging.md#logging-context-metadata-through-rails-or-grape-requests) の形で[メタデータをジョブに追加します。ほとんどの場合、リクエストからジョブをスケジューリングするとき、このコンテキストはすでにリクエストから差し引かれ、スケジューリングされたジョブに追加されます。
ジョブが実行されると、スケジュールされたときにアクティビティだったコンテキストがリストアされます。これによって、コンテキストは、実行中のジョブ内からスケジュールされたすべてのジョブに伝搬されます。
このことは、ほとんどの場合、ジョブにコンテキストを追加するために、何もする必要がないことを意味します。
しかし、ジョブのスケジューリング時にコンテキストが存在しないインスタンスや、存在するコンテキストが正しくない可能性が高いインスタンスもあります。このようなインスタンスに対して、私たちは RuboCop のルールを追加して、注意を喚起し、ログに不正なメタデータを残さないようにしています。
私たちのほとんどの警官と同様に、それらを無効にするための完全に正当な理由があります。この場合、リクエストのコンテキストが正しい可能性があります。あるいは、警官に拾われないような方法ですでにコンテキストを指定しているのかもしれません。いずれにせよ、警官を無効にするときにどのコンテキストを使用するかを示すコードコメントを残してください。
オブジェクトをコンテキストに提供する際には、名前空間とプロジェクトのルートが事前にロードされていることを確認してください。これは、すべてのRoutable
で定義されている.with_route
スコープを使用することで可能です。
cron ワーカー
リクエストからスケジューリングする場合でも、cronjob キュー (include CronjobQueue
) にあるワーカーのコンテキストは自動的にクリアされます。これは cron ワーカーから他のジョブがスケジューリングされたときに不正なメタデータにならないようにするためです。
cron ワーカーはインスタンス全体で動作するので、コンテキストに追加されるべきユーザー、名前空間、プロジェクト、その他のリソースにはスコープされません。
しかし、しばしばコンテキストを必要と_する_他のジョブをスケジュールします。
そのため、Worker のどこかにコンテキストを表示する必要があります。これは、Worker のどこかで以下のメソッドのいずれかを使うことで実現できます:
-
ジョブをスケジュールするコードを
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
-
コンテキストを提供するバッチスケジューリングメソッドを使います:
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_async
をbulk_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 } }
)
第1引数の列挙可能なオブジェクトは、それぞれ2つのブロックに分けられます:
-
arguments_proc
ジョブがスケジューリングされる必要がある引数のリストを返す必要があります。 -
context_proc
ジョブのコンテキスト情報を持つハッシュを返す必要があります。
引数 logging
GitLab 13.6では、Sidekiqジョブの引数はSIDEKIQ_LOG_ARGUMENTS
が無効になっていない限り、デフォルトでログに記録されます。
デフォルトでは、ログに記録される引数は数値引数のみです。他の型の引数には機密情報が含まれる可能性があるからです。これを上書きするには、loggable_arguments
をワーカー内部で使用して、ログに記録する引数のインデックスを指定します (数値引数はここで指定する必要はありません)。
使用例:
class MyWorker
include ApplicationWorker
loggable_arguments 1, 3
# object_id will be logged as it's numeric
# string_a will be logged due to the loggable_arguments call
# string_b will be filtered from logs
# string_c will be logged due to the loggable_arguments call
def perform(object_id, string_a, string_b, string_c)
end
end