rails_semantic_logger 4.15.0 → 4.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bb41dd02df0dc0dc472a66f83a82146878942a309670d4fb10da64bfdae4bc4
4
- data.tar.gz: c1463e8da359c87fffc4e7d4e56919609320473fa0702b6a7f9b9fec1bdc5050
3
+ metadata.gz: 9a96d9dc4eb844eb8561d52f66dc27e2e07edb6b61da2163b0351ce3b12759ff
4
+ data.tar.gz: 34145d723bd89d14e5377200862df57829739b2ee5e5422a58f1d0edd4cbff0f
5
5
  SHA512:
6
- metadata.gz: 1604cdbeed7b9bda178517f7cd7f72e4721523cf222aa6b0a2dcce36fc77c62807641ca32aef349f91c9e5aa86d04e9202e15adff71e4b5e4e29798a3c9dde16
7
- data.tar.gz: b0e79372c2111bb823c191595a600c8c4c218e6989249f66c0ec46d66826116abfe2f6c5c761d33ae23f1494e7a74b8299d70b037410570757195115b212dced
6
+ metadata.gz: e99c63ad9e4d02377d5ea25ba528f5de4fa8f83a2aadd7ef19ef2e3b8f52fc67cd2d08130ec18478ab4e5a2785657928f4e863024d8214a76de3bff4618b6891
7
+ data.tar.gz: 2d6ccc0cb9e385a2ca3a0fdc65023948f968a83b044768fc9bc9ccfb78452d7d4325731cdc4c5397bb097efa1ad72a1ce05d5576429cb2eb05b8c984fa7f06bb
data/README.md CHANGED
@@ -3,12 +3,116 @@
3
3
 
4
4
  Rails Semantic Logger replaces the Rails default logger with [Semantic Logger](https://logger.rocketjob.io/)
5
5
 
6
+ When any large Rails application is deployed to production one of the first steps is to move to centralized logging, so that logs can be viewed and searched from a central location.
7
+
8
+ Centralized logging quickly falls apart when trying to consume the current human readable log files:
9
+ - Log entries often span multiple lines, resulting in unrelated log lines in the centralized logging system. For example, stack traces.
10
+ - Complex Regular Expressions are needed to parse the text lines and make them machine readable. For example to build queries, or alerts that are looking for specific elements in the message.
11
+ - Writing searches, alerts, or dashboards based on text logs is incredibly brittle, since a small change to the text logged can often break the parsing of those logs.
12
+ - Every log entry often has a completely different format, making it difficult to make consistent searches against the data.
13
+
14
+ For these and many other reasons switching to structured logging, or logs in JSON format, in testing and production makes centralized logging incredibly powerful.
15
+
16
+ For example, adding these lines to `config/application.rb` and removing any other log overrides from other environments, will switch automatically to structured logging when running inside Kubernetes:
17
+ ~~~ruby
18
+ # Setup structured logging
19
+ config.semantic_logger.application = "my_application"
20
+ config.semantic_logger.environment = ENV["STACK_NAME"] || Rails.env
21
+ config.log_level = ENV["LOG_LEVEL"] || :info
22
+
23
+ # Switch to JSON Logging output to stdout when running on Kubernetes
24
+ if ENV["LOG_TO_CONSOLE"] || ENV["KUBERNETES_SERVICE_HOST"]
25
+ config.rails_semantic_logger.add_file_appender = false
26
+ config.semantic_logger.add_appender(io: $stdout, formatter: :json)
27
+ end
28
+ ~~~
29
+
30
+ Then configure the centralized logging system to tell it that the data is in JSON format, so that it will parse it for you into a hierarchy.
31
+
32
+ For example, the following will instruct [Observe](https://www.observeinc.com/) to parse the JSON data and create machine readable data from it:
33
+ ~~~ruby
34
+ interface "log", "log":log
35
+
36
+ make_col event:parse_json(log)
37
+
38
+ make_col
39
+ time:parse_isotime(event.timestamp),
40
+ application:string(event.application),
41
+ environment:string(event.environment),
42
+ duration:duration_ms(event.duration_ms),
43
+ level:string(event.level),
44
+ name:string(event.name),
45
+ message:string(event.message),
46
+ named_tags:event.named_tags,
47
+ payload:event.payload,
48
+ metric:string(event.metric),
49
+ metric_amount:float64(event.metric_amount),
50
+ tags:array(event.tags),
51
+ exception:event.exception,
52
+ host:string(event.host),
53
+ pid:int64(event.pid),
54
+ thread:string(event.thread),
55
+ file:string(event.file),
56
+ line:int64(event.line),
57
+ dimensions:event.dimensions,
58
+ backtrace:array(event.backtrace),
59
+ level_index:int64(event.level_index)
60
+
61
+ set_valid_from(time)
62
+ drop_col timestamp, log, event, stream
63
+ rename_col timestamp:time
64
+ ~~~
65
+
66
+ Now queries can be built to drill down into each of these fields, including `payload` which is a nested object.
67
+
68
+ For example to find all failed Sidekiq job calls where the causing exception class name is `NoMethodError`:
69
+ ~~~ruby
70
+ filter environment = "uat2"
71
+ filter level = "error"
72
+ filter metric = "sidekiq.job.perform"
73
+ filter (string(exception.cause.name) = "NoMethodError")
74
+ ~~~
75
+
76
+ Example: create a dashboard showing the duration of all successful Sidekiq jobs:
77
+ ~~~ruby
78
+ filter environment = "production"
79
+ filter level = "info"
80
+ filter metric = "sidekiq.job.perform"
81
+ timechart duration:avg(duration), group_by(name)
82
+ ~~~
83
+
84
+ Example: create a dashboard showing the queue latency of all Sidekiq jobs.
85
+ The queue latency is the time between when the job was enqueued and when it was started:
86
+ ~~~ruby
87
+ filter environment = "production"
88
+ filter level = "info"
89
+ filter metric = "sidekiq.queue.latency"
90
+ timechart latency:avg(metric_amount/1000), group_by(string(named_tags.queue))
91
+ ~~~
92
+
6
93
  * http://github.com/reidmorrison/rails_semantic_logger
7
94
 
8
95
  ## Documentation
9
96
 
10
97
  For complete documentation see: https://logger.rocketjob.io/rails
11
98
 
99
+ ## Upgrading to Semantic Logger V4.16 - Sidekiq Metrics Support
100
+
101
+ Rails Semantic Logger now supports Sidekiq metrics.
102
+ Below are the metrics that are now available when the JSON logging format is used:
103
+ - `sidekiq.job.perform`
104
+ - The duration of each Sidekiq job.
105
+ - `duration` contains the time in milliseconds that the job took to run.
106
+ - `sidekiq.queue.latency`
107
+ - The time between when a Sidekiq job was enqueued and when it was started.
108
+ - `metric_amount` contains the time in milliseconds that the job was waiting in the queue.
109
+
110
+ ## Upgrading to Semantic Logger v4.15 & V4.16 - Sidekiq Support
111
+
112
+ Rails Semantic Logger introduces direct support for Sidekiq v4, v5, v6, and v7.
113
+ Please remove any previous custom patches or configurations to make Sidekiq work with Semantic Logger.
114
+ To see the complete list of patches being made, and to contribute your own changes, see: [Sidekiq Patches](https://github.com/reidmorrison/rails_semantic_logger/blob/master/lib/rails_semantic_logger/extensions/sidekiq/sidekiq.rb)
115
+
12
116
  ## Upgrading to Semantic Logger v4.4
13
117
 
14
118
  With some forking frameworks it is necessary to call `reopen` after the fork. With v4.4 the
@@ -19,7 +123,18 @@ I.e. Please remove the following line if being called anywhere:
19
123
  SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
20
124
  ~~~
21
125
 
22
- ## Supports
126
+ ## New Versions of Rails, etc.
127
+
128
+ The primary purpose of the Rails Semantic Logger gem is to patch other gems, primarily Rails, to make them support structured logging though Semantic Logger.
129
+
130
+ When new versions of Rails and other gems are published they often make changes to the internals, so the existing patches stop working.
131
+
132
+ Rails Semantic Logger survives only when someone in the community upgrades to a newer Rails or other supported libraries, runs into problems,
133
+ and then contributes the fix back to the community by means of a pull request.
134
+
135
+ Additionally, when new popular gems come out, we rely only the community to supply the necessary patches in Rails Semantic Logger to make those gems support structured logging.
136
+
137
+ ## Supported Platforms
23
138
 
24
139
  For the complete list of supported Ruby and Rails versions, see the [Testing file](https://github.com/reidmorrison/rails_semantic_logger/blob/master/.github/workflows/ci.yml).
25
140
 
@@ -108,12 +108,31 @@ module RailsSemanticLogger
108
108
  Resque.logger = SemanticLogger[Resque] if defined?(Resque) && Resque.respond_to?(:logger=)
109
109
 
110
110
  # Replace the Sidekiq logger
111
- if defined?(Sidekiq)
112
- if Sidekiq.respond_to?(:logger=)
113
- Sidekiq.logger = SemanticLogger[Sidekiq]
114
- elsif Sidekiq::VERSION[0..1] == "7."
115
- method = Sidekiq.server? ? :configure_server : :configure_client
116
- Sidekiq.public_send(method) { |cfg| cfg.logger = SemanticLogger[Sidekiq] }
111
+ if defined?(::Sidekiq)
112
+ ::Sidekiq.configure_client do |config|
113
+ config.logger = ::SemanticLogger[::Sidekiq]
114
+ end
115
+
116
+ ::Sidekiq.configure_server do |config|
117
+ config.logger = ::SemanticLogger[::Sidekiq]
118
+ if config.respond_to?(:options)
119
+ config.options[:job_logger] = RailsSemanticLogger::Sidekiq::JobLogger
120
+ else
121
+ config[:job_logger] = RailsSemanticLogger::Sidekiq::JobLogger
122
+ end
123
+
124
+ # Add back the default console logger unless already added
125
+ SemanticLogger.add_appender(io: $stdout, formatter: :color) unless SemanticLogger.appenders.console_output?
126
+
127
+ # Replace default error handler when present
128
+ existing = RailsSemanticLogger::Sidekiq::Defaults.delete_default_error_handler(config.error_handlers)
129
+ config.error_handlers << RailsSemanticLogger::Sidekiq::Defaults::ERROR_HANDLER if existing
130
+ end
131
+
132
+ if defined?(::Sidekiq::Job) && (::Sidekiq::VERSION.to_i != 5)
133
+ ::Sidekiq::Job.singleton_class.prepend(RailsSemanticLogger::Sidekiq::Loggable)
134
+ else
135
+ ::Sidekiq::Worker.singleton_class.prepend(RailsSemanticLogger::Sidekiq::Loggable)
117
136
  end
118
137
  end
119
138
 
@@ -154,7 +173,7 @@ module RailsSemanticLogger
154
173
 
155
174
  if config.rails_semantic_logger.semantic
156
175
  # Active Job
157
- if defined?(::ActiveJob) && defined?(::ActiveJob::Logging::LogSubscriber)
176
+ if defined?(::ActiveJob::Logging::LogSubscriber)
158
177
  RailsSemanticLogger.swap_subscriber(
159
178
  ::ActiveJob::Logging::LogSubscriber,
160
179
  RailsSemanticLogger::ActiveJob::LogSubscriber,
@@ -162,7 +181,7 @@ module RailsSemanticLogger
162
181
  )
163
182
  end
164
183
 
165
- if defined?(::ActiveJob) && defined?(::ActiveJob::LogSubscriber)
184
+ if defined?(::ActiveJob::LogSubscriber)
166
185
  RailsSemanticLogger.swap_subscriber(
167
186
  ::ActiveJob::LogSubscriber,
168
187
  RailsSemanticLogger::ActiveJob::LogSubscriber,
@@ -1,77 +1,14 @@
1
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
2
  if Sidekiq::VERSION.to_i == 4
8
- require "sidekiq/exception_handler"
9
3
  require "sidekiq/logging"
10
4
  require "sidekiq/middleware/server/logging"
11
5
  require "sidekiq/processor"
12
- require "sidekiq/worker"
13
6
  elsif Sidekiq::VERSION.to_i == 5
14
- require "sidekiq/exception_handler"
15
- require "sidekiq/job_logger"
16
7
  require "sidekiq/logging"
17
- require "sidekiq/worker"
18
- elsif Sidekiq::VERSION.to_i == 6 && Sidekiq::VERSION.to_f < 6.5
19
- require "sidekiq/exception_handler"
20
- require "sidekiq/job_logger"
21
- require "sidekiq/worker"
22
- elsif Sidekiq::VERSION.to_i == 6
23
- require "sidekiq/job_logger"
24
- require "sidekiq/worker"
25
- else
26
- require "sidekiq/config"
27
- require "sidekiq/job_logger"
28
- require "sidekiq/job"
29
8
  end
30
9
 
31
10
  module Sidekiq
32
- # Sidekiq > v4
33
- if defined?(::Sidekiq::JobLogger)
34
- # Let Semantic Logger handle duration logging
35
- class JobLogger
36
- def call(item, queue)
37
- klass = item["wrapped"] || item["class"]
38
- metric = "Sidekiq/#{klass}/perform" if klass
39
- logger = klass ? SemanticLogger[klass] : Sidekiq.logger
40
- logger.info("Start #perform")
41
- logger.measure_info(
42
- "Completed #perform",
43
- on_exception_level: :error,
44
- log_exception: :full,
45
- metric: metric
46
- ) do
47
- yield
48
- end
49
- end
50
-
51
- def prepare(job_hash, &block)
52
- level = job_hash["log_level"]
53
- if level
54
- SemanticLogger.silence(level) do
55
- SemanticLogger.tagged(job_hash_context(job_hash), &block)
56
- end
57
- else
58
- SemanticLogger.tagged(job_hash_context(job_hash), &block)
59
- end
60
- end
61
-
62
- def job_hash_context(job_hash)
63
- h = {
64
- class: job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"],
65
- jid: job_hash["jid"]
66
- }
67
- h[:bid] = job_hash["bid"] if job_hash["bid"]
68
- h[:tags] = job_hash["tags"] if job_hash["tags"]
69
- h
70
- end
71
- end
72
- end
73
-
74
- # Sidekiq <= v6
11
+ # Sidekiq v4 & v5
75
12
  if defined?(::Sidekiq::Logging)
76
13
  # Replace Sidekiq logging context
77
14
  module Logging
@@ -80,112 +17,23 @@ module Sidekiq
80
17
  end
81
18
 
82
19
  def self.job_hash_context(job_hash)
83
- klass = job_hash["wrapped"] || job_hash["class"]
84
- event = { class: klass, jid: job_hash["jid"] }
85
- event[:bid] = job_hash["bid"] if job_hash["bid"]
86
- event
87
- end
88
- end
89
- end
90
-
91
- # Exception is already logged by Semantic Logger during the perform call
92
- # Sidekiq <= v6.5
93
- if defined?(::Sidekiq::ExceptionHandler)
94
- module ExceptionHandler
95
- class Logger
96
- def call(ex, ctx)
97
- unless ctx.empty?
98
- job_hash = ctx[:job] || {}
99
- klass = job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
100
- logger = klass ? SemanticLogger[klass] : Sidekiq.logger
101
- ctx[:context] ? logger.warn(ctx[:context], ctx) : logger.warn(ctx)
102
- end
103
- end
104
- end
105
- end
106
- # Sidekiq >= v7
107
- elsif defined?(::Sidekiq::Config)
108
- class Config
109
- remove_const :ERROR_HANDLER
110
-
111
- ERROR_HANDLER = ->(ex, ctx, cfg = Sidekiq.default_configuration) {
112
- unless ctx.empty?
113
- job_hash = ctx[:job] || {}
114
- klass = job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
115
- logger = klass ? SemanticLogger[klass] : Sidekiq.logger
116
- ctx[:context] ? logger.warn(ctx[:context], ctx) : logger.warn(ctx)
117
- end
118
- }
119
- end
120
- else
121
- # Sidekiq >= 6.5
122
- # TODO: Not taking effect. See test/sidekiq_test.rb
123
- def self.default_error_handler(ex, ctx)
124
- binding.irb
125
- unless ctx.empty?
126
- job_hash = ctx[:job] || {}
127
- klass = job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
128
- logger = klass ? SemanticLogger[klass] : Sidekiq.logger
129
- ctx[:context] ? logger.warn(ctx[:context], ctx) : logger.warn(ctx)
130
- end
131
- end
132
- end
133
-
134
- # Logging within each worker should use its own logger
135
- if Sidekiq::VERSION.to_i == 4
136
- module Worker
137
- def self.included(base)
138
- raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
139
-
140
- base.extend(ClassMethods)
141
- base.include(SemanticLogger::Loggable)
142
- base.class_attribute :sidekiq_options_hash
143
- base.class_attribute :sidekiq_retry_in_block
144
- base.class_attribute :sidekiq_retries_exhausted_block
145
- end
146
- end
147
- elsif Sidekiq::VERSION.to_i == 5
148
- module Worker
149
- def self.included(base)
150
- raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
151
-
152
- base.extend(ClassMethods)
153
- base.include(SemanticLogger::Loggable)
154
- base.sidekiq_class_attribute :sidekiq_options_hash
155
- base.sidekiq_class_attribute :sidekiq_retry_in_block
156
- base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
157
- end
158
- end
159
- elsif Sidekiq::VERSION.to_i == 6
160
- module Worker
161
- def self.included(base)
162
- raise ArgumentError, "Sidekiq::Worker cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
163
-
164
- base.include(Options)
165
- base.extend(ClassMethods)
166
- base.include(SemanticLogger::Loggable)
167
- end
168
- end
169
- else
170
- module Job
171
- def self.included(base)
172
- raise ArgumentError, "Sidekiq::Job cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
173
-
174
- base.include(Options)
175
- base.extend(ClassMethods)
176
- base.include(SemanticLogger::Loggable)
20
+ h = {jid: job_hash["jid"]}
21
+ h[:bid] = job_hash["bid"] if job_hash["bid"]
22
+ h[:queue] = job_hash["queue"] if job_hash["queue"]
23
+ h
177
24
  end
178
25
  end
179
26
  end
180
27
 
181
- if Sidekiq::VERSION.to_i == 4
28
+ # Sidekiq v4
29
+ if defined?(::Sidekiq::Middleware::Server::Logging)
182
30
  # Convert string to machine readable format
183
31
  class Processor
184
32
  def log_context(job_hash)
185
- klass = job_hash["wrapped"] || job_hash["class"]
186
- event = { class: klass, jid: job_hash["jid"] }
187
- event[:bid] = job_hash["bid"] if job_hash["bid"]
188
- event
33
+ h = {jid: job_hash["jid"]}
34
+ h[:bid] = job_hash["bid"] if job_hash["bid"]
35
+ h[:queue] = job_hash["queue"] if job_hash["queue"]
36
+ h
189
37
  end
190
38
  end
191
39
 
@@ -193,17 +41,28 @@ module Sidekiq
193
41
  module Middleware
194
42
  module Server
195
43
  class Logging
44
+ # rubocop:disable Style/ExplicitBlockArgument
196
45
  def call(worker, item, queue)
197
- worker.logger.info("Start #perform")
198
- worker.logger.measure_info(
199
- "Completed #perform",
200
- on_exception_level: :error,
201
- log_exception: :full,
202
- metric: "Sidekiq/#{worker.class.name}/perform"
203
- ) do
204
- yield
46
+ SemanticLogger.tagged(queue: queue) do
47
+ worker.logger.info(
48
+ "Start #perform",
49
+ metric: "sidekiq.queue.latency",
50
+ metric_amount: job_latency_ms(item)
51
+ )
52
+ worker.logger.measure_info(
53
+ "Completed #perform",
54
+ on_exception_level: :error,
55
+ log_exception: :full,
56
+ metric: "sidekiq.job.perform"
57
+ ) { yield }
205
58
  end
206
59
  end
60
+
61
+ def job_latency_ms(job)
62
+ return unless job && job["enqueued_at"]
63
+
64
+ (Time.now.to_f - job["enqueued_at"].to_f) * 1000
65
+ end
207
66
  end
208
67
  end
209
68
  end
@@ -0,0 +1,40 @@
1
+ module RailsSemanticLogger
2
+ module Sidekiq
3
+ module Defaults
4
+ # Prevent exception logging during standard error handling since the Job Logger below already logs the exception.
5
+ ERROR_HANDLER =
6
+ if ::Sidekiq::VERSION.to_f < 7.1 ||
7
+ (::Sidekiq::VERSION.to_f == 7.1 && ::Sidekiq::VERSION.split(".").last.to_i < 6)
8
+ lambda do |_ex, ctx|
9
+ unless ctx.empty?
10
+ job_hash = ctx[:job] || {}
11
+ klass = job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
12
+ logger = klass ? SemanticLogger[klass] : Sidekiq.logger
13
+ ctx[:context] ? logger.warn(ctx[:context], ctx) : logger.warn(ctx)
14
+ end
15
+ end
16
+ else
17
+ lambda do |_ex, ctx, _default_configuration|
18
+ unless ctx.empty?
19
+ job_hash = ctx[:job] || {}
20
+ klass = job_hash["display_class"] || job_hash["wrapped"] || job_hash["class"]
21
+ logger = klass ? SemanticLogger[klass] : Sidekiq.logger
22
+ ctx[:context] ? logger.warn(ctx[:context], ctx) : logger.warn(ctx)
23
+ end
24
+ end
25
+ end
26
+
27
+ # Returns the default logger after removing from the supplied list.
28
+ # Returns [nil] when the default logger was not present.
29
+ def self.delete_default_error_handler(error_handlers)
30
+ return error_handlers.delete(::Sidekiq::Config::ERROR_HANDLER) if defined?(::Sidekiq::Config::ERROR_HANDLER)
31
+ return error_handlers.delete(::Sidekiq::DEFAULT_ERROR_HANDLER) if defined?(::Sidekiq::DEFAULT_ERROR_HANDLER)
32
+
33
+ return unless defined?(::Sidekiq::ExceptionHandler)
34
+
35
+ existing = error_handlers.find { |handler| handler.is_a?(::Sidekiq::ExceptionHandler::Logger) }
36
+ error_handlers.delete(existing) if existing
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,59 @@
1
+ module RailsSemanticLogger
2
+ module Sidekiq
3
+ class JobLogger
4
+ # Sidekiq 6.5 does not take any arguments, whereas v7 is given a logger
5
+ def initialize(*_args)
6
+ end
7
+
8
+ def call(item, queue, &block)
9
+ klass = item["wrapped"] || item["class"]
10
+ logger = klass ? SemanticLogger[klass] : Sidekiq.logger
11
+
12
+ SemanticLogger.tagged(queue: queue) do
13
+ # Latency is the time between when the job was enqueued and when it started executing.
14
+ logger.info(
15
+ "Start #perform",
16
+ metric: "sidekiq.queue.latency",
17
+ metric_amount: job_latency_ms(item)
18
+ )
19
+
20
+ # Measure the duration of running the job
21
+ logger.measure_info(
22
+ "Completed #perform",
23
+ on_exception_level: :error,
24
+ log_exception: :full,
25
+ metric: "sidekiq.job.perform",
26
+ &block
27
+ )
28
+ end
29
+ end
30
+
31
+ def prepare(job_hash, &block)
32
+ level = job_hash["log_level"]
33
+ if level
34
+ SemanticLogger.silence(level) do
35
+ SemanticLogger.tagged(job_hash_context(job_hash), &block)
36
+ end
37
+ else
38
+ SemanticLogger.tagged(job_hash_context(job_hash), &block)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def job_hash_context(job_hash)
45
+ h = {jid: job_hash["jid"]}
46
+ h[:bid] = job_hash["bid"] if job_hash["bid"]
47
+ h[:tags] = job_hash["tags"] if job_hash["tags"]
48
+ h[:queue] = job_hash["queue"] if job_hash["queue"]
49
+ h
50
+ end
51
+
52
+ def job_latency_ms(job)
53
+ return unless job && job["enqueued_at"]
54
+
55
+ (Time.now.to_f - job["enqueued_at"].to_f) * 1000
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,10 @@
1
+ module RailsSemanticLogger
2
+ module Sidekiq
3
+ module Loggable
4
+ def included(base)
5
+ super
6
+ base.include(SemanticLogger::Loggable)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsSemanticLogger
2
- VERSION = "4.15.0".freeze
2
+ VERSION = "4.17.0".freeze
3
3
  end
@@ -31,6 +31,12 @@ module RailsSemanticLogger
31
31
  autoload :Plugin, "rails_semantic_logger/delayed_job/plugin"
32
32
  end
33
33
 
34
+ module Sidekiq
35
+ autoload :Defaults, "rails_semantic_logger/sidekiq/defaults"
36
+ autoload :JobLogger, "rails_semantic_logger/sidekiq/job_logger"
37
+ autoload :Loggable, "rails_semantic_logger/sidekiq/loggable"
38
+ end
39
+
34
40
  autoload :Options, "rails_semantic_logger/options"
35
41
 
36
42
  # Swap an existing subscriber with a new one
@@ -69,7 +75,7 @@ require("rails_semantic_logger/extensions/active_support/logger") if defined?(Ac
69
75
  require("rails_semantic_logger/extensions/active_support/log_subscriber") if defined?(ActiveSupport::LogSubscriber)
70
76
 
71
77
  begin
72
- require 'rackup'
78
+ require "rackup"
73
79
  rescue LoadError
74
80
  # No need to do anything, will fall back to Rack
75
81
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.15.0
4
+ version: 4.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-27 00:00:00.000000000 Z
11
+ date: 2024-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4.13'
47
+ version: '4.16'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.13'
54
+ version: '4.16'
55
55
  description:
56
56
  email:
57
57
  executables: []
@@ -85,6 +85,9 @@ files:
85
85
  - lib/rails_semantic_logger/extensions/sidekiq/sidekiq.rb
86
86
  - lib/rails_semantic_logger/options.rb
87
87
  - lib/rails_semantic_logger/rack/logger.rb
88
+ - lib/rails_semantic_logger/sidekiq/defaults.rb
89
+ - lib/rails_semantic_logger/sidekiq/job_logger.rb
90
+ - lib/rails_semantic_logger/sidekiq/loggable.rb
88
91
  - lib/rails_semantic_logger/version.rb
89
92
  homepage: https://logger.rocketjob.io
90
93
  licenses:
@@ -92,7 +95,7 @@ licenses:
92
95
  metadata:
93
96
  bug_tracker_uri: https://github.com/reidmorrison/rails_semantic_logger/issues
94
97
  documentation_uri: https://logger.rocketjob.io
95
- source_code_uri: https://github.com/reidmorrison/rails_semantic_logger/tree/v4.15.0
98
+ source_code_uri: https://github.com/reidmorrison/rails_semantic_logger/tree/v4.17.0
96
99
  rubygems_mfa_required: 'true'
97
100
  post_install_message:
98
101
  rdoc_options: []