|
| 1 | +# Sidekiq patches |
| 2 | +# |
| 3 | +# To re-enable stdout logging for sidekiq server processes, add the following snippet to config/initializers/sidekiq.rb: |
| 4 | +# Sidekiq.configure_server do |config| |
| 5 | +# SemanticLogger.add_appender(io: $stdout, level: :debug, formatter: :color) |
| 6 | +# end |
| 7 | +if Sidekiq::VERSION.to_i == 4 |
| 8 | + require "sidekiq/exception_handler" |
| 9 | + require "sidekiq/logging" |
| 10 | + require "sidekiq/middleware/server/logging" |
| 11 | + require "sidekiq/processor" |
| 12 | + require "sidekiq/worker" |
| 13 | +elsif Sidekiq::VERSION.to_i == 5 |
| 14 | + require "sidekiq/exception_handler" |
| 15 | + require "sidekiq/job_logger" |
| 16 | + require "sidekiq/logging" |
| 17 | + require "sidekiq/worker" |
| 18 | +elsif Sidekiq::VERSION.to_i > 5 |
| 19 | + require "sidekiq/exception_handler" |
| 20 | + require "sidekiq/job_logger" |
| 21 | + require "sidekiq/worker" |
| 22 | +end |
| 23 | + |
| 24 | +module Sidekiq |
| 25 | + if Sidekiq::VERSION.to_i > 4 |
| 26 | + # Let Semantic Logger handle duration logging |
| 27 | + class JobLogger |
| 28 | + def call(item, queue) |
| 29 | + klass = item["wrapped"] || item["class"] |
| 30 | + metric = "Sidekiq/#{klass}/perform" if klass |
| 31 | + logger = klass ? SemanticLogger[klass] : Sidekiq.logger |
| 32 | + logger.info("Start #perform") |
| 33 | + logger.measure_info( |
| 34 | + "Completed #perform", |
| 35 | + on_exception_level: :error, |
| 36 | + log_exception: :full, |
| 37 | + metric: metric |
| 38 | + ) do |
| 39 | + yield |
| 40 | + end |
| 41 | + end |
| 42 | + |
| 43 | + def prepare(job_hash, &block) |
| 44 | + level = job_hash["log_level"] |
| 45 | + if level |
| 46 | + SemanticLogger.silence(level) do |
| 47 | + SemanticLogger.tagged(job_hash_context(job_hash), &block) |
| 48 | + end |
| 49 | + else |
| 50 | + SemanticLogger.tagged(job_hash_context(job_hash), &block) |
| 51 | + end |
| 52 | + end |
| 53 | + end |
| 54 | + end |
| 55 | + |
| 56 | + if Sidekiq::VERSION.to_i <= 6 |
| 57 | + # Replace Sidekiq logging context |
| 58 | + module Logging |
| 59 | + def self.with_context(msg, &block) |
| 60 | + SemanticLogger.tagged(msg, &block) |
| 61 | + end |
| 62 | + |
| 63 | + def self.job_hash_context(job_hash) |
| 64 | + klass = job_hash["wrapped"] || job_hash["class"] |
| 65 | + event = { class: klass, jid: job_hash["jid"] } |
| 66 | + event[:bid] = job_hash["bid"] if job_hash["bid"] |
| 67 | + event |
| 68 | + end |
| 69 | + end |
| 70 | + end |
| 71 | + |
| 72 | + # Exception is already logged by Semantic Logger during the perform call |
| 73 | + module ExceptionHandler |
| 74 | + class Logger |
| 75 | + def call(ex, ctx) |
| 76 | + Sidekiq.logger.warn(ctx) if !ctx.empty? |
| 77 | + end |
| 78 | + end |
| 79 | + end |
| 80 | + |
| 81 | + module Worker |
| 82 | + # Logging within each worker should use its own logger |
| 83 | + if Sidekiq::VERSION.to_i == 4 |
| 84 | + def self.included(base) |
| 85 | + raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" } |
| 86 | + |
| 87 | + base.extend(ClassMethods) |
| 88 | + base.include(SemanticLogger::Loggable) |
| 89 | + base.class_attribute :sidekiq_options_hash |
| 90 | + base.class_attribute :sidekiq_retry_in_block |
| 91 | + base.class_attribute :sidekiq_retries_exhausted_block |
| 92 | + end |
| 93 | + elsif Sidekiq::VERSION.to_i == 5 |
| 94 | + def self.included(base) |
| 95 | + raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" } |
| 96 | + |
| 97 | + base.extend(ClassMethods) |
| 98 | + base.include(SemanticLogger::Loggable) |
| 99 | + base.sidekiq_class_attribute :sidekiq_options_hash |
| 100 | + base.sidekiq_class_attribute :sidekiq_retry_in_block |
| 101 | + base.sidekiq_class_attribute :sidekiq_retries_exhausted_block |
| 102 | + end |
| 103 | + elsif Sidekiq::VERSION.to_i > 5 |
| 104 | + def self.included(base) |
| 105 | + raise ArgumentError, "Sidekiq::Worker cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" } |
| 106 | + |
| 107 | + base.include(Options) |
| 108 | + base.extend(ClassMethods) |
| 109 | + base.include(SemanticLogger::Loggable) |
| 110 | + end |
| 111 | + end |
| 112 | + end |
| 113 | + |
| 114 | + if Sidekiq::VERSION.to_i == 4 |
| 115 | + # Convert string to machine readable format |
| 116 | + class Processor |
| 117 | + def log_context(item) |
| 118 | + event = { jid: item["jid"] } |
| 119 | + event[:bid] = item["bid"] if item["bid"] |
| 120 | + event |
| 121 | + end |
| 122 | + end |
| 123 | + |
| 124 | + # Let Semantic Logger handle duration logging |
| 125 | + module Middleware |
| 126 | + module Server |
| 127 | + class Logging |
| 128 | + def call(worker, item, queue) |
| 129 | + worker.logger.info("Start #perform") |
| 130 | + worker.logger.measure_info( |
| 131 | + "Completed #perform", |
| 132 | + on_exception_level: :error, |
| 133 | + log_exception: :full, |
| 134 | + metric: "Sidekiq/#{worker.class.name}/perform" |
| 135 | + ) do |
| 136 | + yield |
| 137 | + end |
| 138 | + end |
| 139 | + end |
| 140 | + end |
| 141 | + end |
| 142 | + end |
| 143 | +end |
0 commit comments