log_bench 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +76 -0
- data/lib/log_bench/app/main.rb +1 -1
- data/lib/log_bench/app/state.rb +18 -1
- data/lib/log_bench/current.rb +1 -1
- data/lib/log_bench/job_prefix_formatter.rb +46 -0
- data/lib/log_bench/json_formatter.rb +52 -11
- data/lib/log_bench/log/collection.rb +4 -1
- data/lib/log_bench/log/entry.rb +2 -3
- data/lib/log_bench/log/job_enqueue_entry.rb +23 -0
- data/lib/log_bench/log/parser.rb +57 -1
- data/lib/log_bench/railtie.rb +7 -0
- data/lib/log_bench/sidekiq_middleware.rb +32 -0
- data/lib/log_bench/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e09eee0378110cca913cb1611c4b299a874dc025c7be07fcde2e89a48be8c010
|
|
4
|
+
data.tar.gz: 92bb7b5373652fb947534380d996ce052099e301968c28d3e44b878a1cdce180
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f75eb599a35ef1717eda389dbd2919134374922d14b6c4ff1b1c8b98c6f13138feec808b458aea78be882e557cb5a058142dbdf2717386347e3d6ad57e70e208
|
|
7
|
+
data.tar.gz: 9564662777ca62c550ec723240a25e5ff97f968734cac13845810ed8a207d5dec296d8ef1bbf2f2c193b7d8dc603ea14ab7fa2f6a21de6072275f9917a958991
|
data/README.md
CHANGED
|
@@ -187,6 +187,82 @@ LogBench works with JSON-formatted logs. Each log entry should include:
|
|
|
187
187
|
- `message`: SQL query with timing information
|
|
188
188
|
- `request_id`: Links query to HTTP request
|
|
189
189
|
|
|
190
|
+
## Job Logging
|
|
191
|
+
|
|
192
|
+
LogBench provides enhanced logging for background jobs with colored job prefixes in the TUI. Job logs are automatically prefixed with `[JobClass#job-id]` in orange/yellow color for easy identification.
|
|
193
|
+
|
|
194
|
+
### ActiveJob
|
|
195
|
+
|
|
196
|
+
For **ActiveJob** classes, use the job's `logger` method (not `Rails.logger`) to ensure logs get proper job context:
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
class EmailDeliveryJob < ApplicationJob
|
|
200
|
+
def perform(user_id)
|
|
201
|
+
logger.info "Starting email delivery for user #{user_id}" # ✅ Will have job prefix
|
|
202
|
+
|
|
203
|
+
user = User.find(user_id)
|
|
204
|
+
logger.info "Found user: #{user.email}" # ✅ Will have job prefix
|
|
205
|
+
|
|
206
|
+
# SQL queries are automatically tagged
|
|
207
|
+
user.update!(last_email_sent_at: Time.current) # ✅ Will have job prefix
|
|
208
|
+
|
|
209
|
+
logger.info "Email delivery completed" # ✅ Will have job prefix
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**❌ Don't use `Rails.logger` in ActiveJob:**
|
|
215
|
+
```ruby
|
|
216
|
+
class EmailDeliveryJob < ApplicationJob
|
|
217
|
+
def perform(user_id)
|
|
218
|
+
Rails.logger.info "This won't have job prefix" # ❌ No job context
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Plain Sidekiq Jobs
|
|
224
|
+
|
|
225
|
+
For **plain Sidekiq** jobs (not using ActiveJob), LogBench automatically captures job context:
|
|
226
|
+
|
|
227
|
+
```ruby
|
|
228
|
+
class DataProcessingJob
|
|
229
|
+
include Sidekiq::Job
|
|
230
|
+
|
|
231
|
+
def perform(data_id)
|
|
232
|
+
Rails.logger.info "Processing data #{data_id}" # ✅ Will have job prefix
|
|
233
|
+
|
|
234
|
+
# SQL queries are automatically tagged
|
|
235
|
+
data = Data.find(data_id) # ✅ Will have job prefix
|
|
236
|
+
data.process!
|
|
237
|
+
|
|
238
|
+
Rails.logger.info "Data processing completed" # ✅ Will have job prefix
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Job Log Output
|
|
244
|
+
|
|
245
|
+
In the TUI, job-related logs appear with colored prefixes:
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
🟡[EmailDeliveryJob#email-job-123] Starting email delivery for user 456
|
|
249
|
+
🟡[EmailDeliveryJob#email-job-123] Found user: user@example.com
|
|
250
|
+
🟡[EmailDeliveryJob#email-job-123] User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1
|
|
251
|
+
🟡[EmailDeliveryJob#email-job-123] Email delivery completed
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
*(🟡 represents yellow bold colored job name, consistent with Rails SQL query coloring)*
|
|
255
|
+
|
|
256
|
+
### Job Context Detection
|
|
257
|
+
|
|
258
|
+
LogBench automatically detects job context through:
|
|
259
|
+
|
|
260
|
+
- **ActiveJob**: Uses Rails' tagged logging system with job class and job ID
|
|
261
|
+
- **Plain Sidekiq**: Uses LogBench::Current attributes set by Sidekiq middleware
|
|
262
|
+
- **SQL Queries**: Inherit job context from the current request/job execution
|
|
263
|
+
|
|
264
|
+
No additional configuration is required - job logging works automatically once LogBench is installed.
|
|
265
|
+
|
|
190
266
|
## Testing
|
|
191
267
|
|
|
192
268
|
LogBench includes a comprehensive test suite to ensure reliability and correctness.
|
data/lib/log_bench/app/main.rb
CHANGED
data/lib/log_bench/app/state.rb
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "singleton"
|
|
4
|
+
|
|
3
5
|
module LogBench
|
|
4
6
|
module App
|
|
5
7
|
class State
|
|
8
|
+
include Singleton
|
|
9
|
+
|
|
6
10
|
attr_reader :main_filter, :sort, :detail_filter, :cleared_requests
|
|
7
11
|
attr_accessor :requests, :orphan_requests, :auto_scroll, :scroll_offset, :selected, :detail_scroll_offset, :detail_selected_entry, :text_selection_mode, :update_available, :update_version
|
|
8
12
|
|
|
9
13
|
def initialize
|
|
14
|
+
reset!
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def reset!
|
|
10
18
|
self.requests = []
|
|
11
19
|
self.orphan_requests = []
|
|
12
20
|
self.selected = 0
|
|
@@ -23,6 +31,7 @@ module LogBench
|
|
|
23
31
|
self.update_available = false
|
|
24
32
|
self.update_version = nil
|
|
25
33
|
self.cleared_requests = nil
|
|
34
|
+
self.job_ids_map = {}
|
|
26
35
|
end
|
|
27
36
|
|
|
28
37
|
def running?
|
|
@@ -280,9 +289,17 @@ module LogBench
|
|
|
280
289
|
end
|
|
281
290
|
end
|
|
282
291
|
|
|
292
|
+
def register_job_enqueue(job_id, request_id)
|
|
293
|
+
job_ids_map[job_id] = request_id
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def request_id_for_job(job_id)
|
|
297
|
+
job_ids_map[job_id]
|
|
298
|
+
end
|
|
299
|
+
|
|
283
300
|
private
|
|
284
301
|
|
|
285
|
-
attr_accessor :focused_pane, :running
|
|
302
|
+
attr_accessor :focused_pane, :running, :job_ids_map
|
|
286
303
|
attr_writer :main_filter, :detail_filter, :sort, :cleared_requests
|
|
287
304
|
end
|
|
288
305
|
end
|
data/lib/log_bench/current.rb
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LogBench
|
|
4
|
+
# Shared module for formatting job prefixes with ANSI colors
|
|
5
|
+
# Used by both JsonFormatter (when writing logs) and Parser (when reading old logs)
|
|
6
|
+
module JobPrefixFormatter
|
|
7
|
+
# Job color palette - using standard colors only (no bright colors)
|
|
8
|
+
JOB_COLORS = [
|
|
9
|
+
31, # Red
|
|
10
|
+
32, # Green
|
|
11
|
+
33, # Yellow
|
|
12
|
+
34, # Blue
|
|
13
|
+
35, # Magenta
|
|
14
|
+
36 # Cyan
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
# Extract job info from ActiveJob tags
|
|
18
|
+
# Returns [job_id, job_class] or nil if not a valid ActiveJob tag
|
|
19
|
+
def extract_job_info_from_tags(tags)
|
|
20
|
+
return nil unless tags.is_a?(Array) && tags.size >= 3
|
|
21
|
+
return nil unless tags[0] == "ActiveJob"
|
|
22
|
+
|
|
23
|
+
# ActiveJob tags format: ["ActiveJob", "JobClassName", "job-id"]
|
|
24
|
+
job_class = tags[1]
|
|
25
|
+
job_id = tags[2]
|
|
26
|
+
return nil unless job_class && job_id
|
|
27
|
+
|
|
28
|
+
[job_id, job_class]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Build colored job prefix using ANSI color codes
|
|
32
|
+
def build_colored_job_prefix(job_class, job_id)
|
|
33
|
+
# Pick a color based on the job ID for visual differentiation
|
|
34
|
+
color_code = pick_job_color(job_id)
|
|
35
|
+
"\u001b[1m\u001b[#{color_code}m[#{job_class}##{job_id}]\u001b[0m"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Pick a consistent color for a job based on its ID
|
|
39
|
+
def pick_job_color(job_id)
|
|
40
|
+
# Use a simple hash of the job ID to pick a consistent color
|
|
41
|
+
# This ensures the same job ID always gets the same color
|
|
42
|
+
hash = job_id.to_s.bytes.sum
|
|
43
|
+
JOB_COLORS[hash % JOB_COLORS.length]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -8,6 +8,7 @@ module LogBench
|
|
|
8
8
|
# JSON logs. Extends TaggedLogging::Formatter for full Rails compatibility.
|
|
9
9
|
class JsonFormatter < ::Logger::Formatter
|
|
10
10
|
include ActiveSupport::TaggedLogging::Formatter
|
|
11
|
+
include JobPrefixFormatter
|
|
11
12
|
|
|
12
13
|
def call(severity, timestamp, progname, message)
|
|
13
14
|
log_entry = build_log_entry(severity, timestamp, progname, message)
|
|
@@ -25,6 +26,15 @@ module LogBench
|
|
|
25
26
|
entry = parse_lograge_message(entry[:message]) if lograge_message?(entry)
|
|
26
27
|
request_id = current_request_id
|
|
27
28
|
|
|
29
|
+
# Get job info from Current attributes (direct Sidekiq jobs) or tags (ActiveJob)
|
|
30
|
+
job_id, job_class = get_job_info(tags)
|
|
31
|
+
|
|
32
|
+
# Add colored job prefix to message if we're in a job context
|
|
33
|
+
if job_id && job_class && entry[:message]
|
|
34
|
+
job_prefix = build_colored_job_prefix(job_class, job_id)
|
|
35
|
+
entry[:message] = "#{job_prefix} #{entry[:message]}"
|
|
36
|
+
end
|
|
37
|
+
|
|
28
38
|
base_entry = {
|
|
29
39
|
level: severity,
|
|
30
40
|
timestamp: timestamp.utc.iso8601(3),
|
|
@@ -74,19 +84,50 @@ module LogBench
|
|
|
74
84
|
end
|
|
75
85
|
|
|
76
86
|
def current_request_id
|
|
77
|
-
request_id
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
get_current_attribute(:request_id)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def current_jid
|
|
91
|
+
get_current_attribute(:jid)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def current_job_class
|
|
95
|
+
get_current_attribute(:job_class)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Generic method to get current attributes from various storage mechanisms
|
|
99
|
+
def get_current_attribute(attribute_name)
|
|
100
|
+
# Try LogBench::Current first (preferred)
|
|
101
|
+
if defined?(LogBench::Current) && LogBench::Current.respond_to?(attribute_name)
|
|
102
|
+
return LogBench::Current.public_send(attribute_name)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Try Current (fallback for apps that define their own Current)
|
|
106
|
+
if defined?(Current) && Current.respond_to?(attribute_name)
|
|
107
|
+
return Current.public_send(attribute_name)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Try RequestStore (for apps using request_store gem)
|
|
111
|
+
if defined?(RequestStore) && RequestStore.exist?(attribute_name)
|
|
112
|
+
return RequestStore.read(attribute_name)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Try Thread local storage (last resort)
|
|
116
|
+
Thread.current[attribute_name]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Get job info from Current attributes (direct Sidekiq jobs) or tags (ActiveJob)
|
|
120
|
+
def get_job_info(tags)
|
|
121
|
+
# First try Current attributes (for direct Sidekiq jobs)
|
|
122
|
+
current_jid = get_current_attribute(:jid)
|
|
123
|
+
current_job_class = get_current_attribute(:job_class)
|
|
124
|
+
|
|
125
|
+
if current_jid && current_job_class
|
|
126
|
+
return [current_jid, current_job_class]
|
|
87
127
|
end
|
|
88
128
|
|
|
89
|
-
|
|
129
|
+
# Fallback to tags (for ActiveJob)
|
|
130
|
+
extract_job_info_from_tags(tags)
|
|
90
131
|
end
|
|
91
132
|
end
|
|
92
133
|
end
|
|
@@ -8,6 +8,7 @@ module LogBench
|
|
|
8
8
|
attr_accessor :entries
|
|
9
9
|
|
|
10
10
|
def initialize(input)
|
|
11
|
+
self.parsed_entries = nil
|
|
11
12
|
self.entries = parse_input(input)
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -59,6 +60,8 @@ module LogBench
|
|
|
59
60
|
|
|
60
61
|
private
|
|
61
62
|
|
|
63
|
+
attr_accessor :parsed_entries
|
|
64
|
+
|
|
62
65
|
def create_collection_from_requests(requests)
|
|
63
66
|
new_collection = self.class.new([])
|
|
64
67
|
new_collection.entries = requests
|
|
@@ -67,7 +70,7 @@ module LogBench
|
|
|
67
70
|
|
|
68
71
|
def parse_input(input)
|
|
69
72
|
lines = normalize_input(input)
|
|
70
|
-
parsed_entries = Parser.parse_lines(lines)
|
|
73
|
+
self.parsed_entries = Parser.parse_lines(lines)
|
|
71
74
|
Parser.group_by_request(parsed_entries)
|
|
72
75
|
end
|
|
73
76
|
|
data/lib/log_bench/log/entry.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module LogBench
|
|
4
4
|
module Log
|
|
5
5
|
class Entry
|
|
6
|
-
attr_reader :type, :raw_line, :request_id, :timestamp, :content, :timing
|
|
6
|
+
attr_reader :type, :raw_line, :request_id, :timestamp, :content, :timing, :json_data
|
|
7
7
|
|
|
8
8
|
def initialize(json_data)
|
|
9
9
|
self.json_data = json_data
|
|
@@ -23,8 +23,7 @@ module LogBench
|
|
|
23
23
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
|
-
attr_writer :type, :timestamp, :request_id, :content, :timing
|
|
27
|
-
attr_accessor :json_data
|
|
26
|
+
attr_writer :type, :timestamp, :request_id, :content, :timing, :json_data
|
|
28
27
|
|
|
29
28
|
def parse_timestamp(timestamp_str)
|
|
30
29
|
return Time.now unless timestamp_str
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LogBench
|
|
4
|
+
module Log
|
|
5
|
+
class JobEnqueueEntry < Entry
|
|
6
|
+
attr_reader :job_id
|
|
7
|
+
|
|
8
|
+
def initialize(json_data)
|
|
9
|
+
super
|
|
10
|
+
self.type = :job_enqueue
|
|
11
|
+
self.job_id = extract_job_id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
attr_writer :job_id
|
|
17
|
+
|
|
18
|
+
def extract_job_id
|
|
19
|
+
Parser.extract_job_id_from_enqueue(content)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/log_bench/log/parser.rb
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
module LogBench
|
|
4
4
|
module Log
|
|
5
5
|
class Parser
|
|
6
|
+
extend JobPrefixFormatter
|
|
7
|
+
|
|
6
8
|
def self.parse_line(raw_line)
|
|
7
9
|
clean_line = raw_line.encode("UTF-8", invalid: :replace, undef: :replace, replace: "").strip
|
|
8
10
|
data = JSON.parse(clean_line)
|
|
9
11
|
return unless data.is_a?(Hash)
|
|
10
12
|
|
|
11
|
-
build_specific_entry(data)
|
|
13
|
+
entry = build_specific_entry(data)
|
|
14
|
+
register_job_enqueue(entry)
|
|
15
|
+
enrich_job_entry(entry)
|
|
16
|
+
entry
|
|
12
17
|
rescue JSON::ParserError
|
|
13
18
|
nil
|
|
14
19
|
end
|
|
@@ -32,6 +37,8 @@ module LogBench
|
|
|
32
37
|
QueryEntry.new(data, cached: true)
|
|
33
38
|
when :sql_call_line
|
|
34
39
|
CallLineEntry.new(data)
|
|
40
|
+
when :job_enqueue
|
|
41
|
+
JobEnqueueEntry.new(data)
|
|
35
42
|
else
|
|
36
43
|
Entry.new(data)
|
|
37
44
|
end
|
|
@@ -67,6 +74,7 @@ module LogBench
|
|
|
67
74
|
return :cache if cache_message?(data)
|
|
68
75
|
return :sql if sql_message?(data)
|
|
69
76
|
return :sql_call_line if call_stack_message?(data)
|
|
77
|
+
return :job_enqueue if job_enqueue_message?(data)
|
|
70
78
|
|
|
71
79
|
:other
|
|
72
80
|
end
|
|
@@ -89,6 +97,54 @@ module LogBench
|
|
|
89
97
|
message = data["message"] || ""
|
|
90
98
|
message.include?("↳")
|
|
91
99
|
end
|
|
100
|
+
|
|
101
|
+
def self.job_enqueue_message?(data)
|
|
102
|
+
message = data["message"] || ""
|
|
103
|
+
message.match?(/Enqueued .+ \(Job ID: .+\)/)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def self.extract_job_id_from_enqueue(message)
|
|
107
|
+
match = message.match(/Job ID: ([^\)]+)/)
|
|
108
|
+
match[1] if match
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Register job enqueue in State
|
|
112
|
+
def self.register_job_enqueue(entry)
|
|
113
|
+
return unless entry.is_a?(JobEnqueueEntry)
|
|
114
|
+
return unless defined?(App::State)
|
|
115
|
+
|
|
116
|
+
App::State.instance.register_job_enqueue(entry.job_id, entry.request_id)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Enrich job execution logs with request_id and colored prefix
|
|
120
|
+
def self.enrich_job_entry(entry)
|
|
121
|
+
return unless entry.respond_to?(:json_data)
|
|
122
|
+
|
|
123
|
+
tags = entry.json_data["tags"]
|
|
124
|
+
job_id, job_class = extract_job_info_from_tags(tags)
|
|
125
|
+
return unless job_id
|
|
126
|
+
|
|
127
|
+
add_job_prefix_to_entry(entry, job_id, job_class)
|
|
128
|
+
add_request_id_to_entry(entry, job_id)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Add colored job prefix to entry content
|
|
132
|
+
def self.add_job_prefix_to_entry(entry, job_id, job_class)
|
|
133
|
+
return if entry.content.match?(/\[[\w:]+#[^\]]+\]/)
|
|
134
|
+
|
|
135
|
+
job_prefix = build_colored_job_prefix(job_class, job_id)
|
|
136
|
+
new_content = "#{job_prefix} #{entry.content}"
|
|
137
|
+
entry.instance_variable_set(:@content, new_content)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Add request_id to entry from State
|
|
141
|
+
def self.add_request_id_to_entry(entry, job_id)
|
|
142
|
+
return if entry.request_id
|
|
143
|
+
return unless defined?(App::State)
|
|
144
|
+
|
|
145
|
+
request_id = App::State.instance.request_id_for_job(job_id)
|
|
146
|
+
entry.instance_variable_set(:@request_id, request_id) if request_id
|
|
147
|
+
end
|
|
92
148
|
end
|
|
93
149
|
end
|
|
94
150
|
end
|
data/lib/log_bench/railtie.rb
CHANGED
|
@@ -102,6 +102,13 @@ module LogBench
|
|
|
102
102
|
|
|
103
103
|
require "sidekiq/middleware/current_attributes"
|
|
104
104
|
Sidekiq::CurrentAttributes.persist("LogBench::Current")
|
|
105
|
+
|
|
106
|
+
# Add our custom middleware to capture job ID
|
|
107
|
+
Sidekiq.configure_server do |config|
|
|
108
|
+
config.server_middleware do |chain|
|
|
109
|
+
chain.add LogBench::SidekiqMiddleware
|
|
110
|
+
end
|
|
111
|
+
end
|
|
105
112
|
end
|
|
106
113
|
|
|
107
114
|
# Validate that LogBench setup worked correctly
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LogBench
|
|
4
|
+
# Sidekiq middleware to capture job ID (jid) and job class name and set them in Current attributes
|
|
5
|
+
# for inclusion in JSON logs
|
|
6
|
+
class SidekiqMiddleware
|
|
7
|
+
def call(worker, job, _queue)
|
|
8
|
+
if defined?(LogBench::Current)
|
|
9
|
+
# Only set Current attributes for direct Sidekiq jobs
|
|
10
|
+
# ActiveJob jobs will use tags instead
|
|
11
|
+
unless activejob_wrapper?(job["class"])
|
|
12
|
+
LogBench::Current.jid = job["jid"]
|
|
13
|
+
LogBench::Current.job_class = job["class"] || worker.class.name
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
yield
|
|
18
|
+
ensure
|
|
19
|
+
if defined?(LogBench::Current)
|
|
20
|
+
# Clean up the job attributes after the job completes
|
|
21
|
+
LogBench::Current.jid = nil
|
|
22
|
+
LogBench::Current.job_class = nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def activejob_wrapper?(job_class)
|
|
29
|
+
job_class == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/log_bench/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: log_bench
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Benjamín Silva
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-10-
|
|
10
|
+
date: 2025-10-17 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: zeitwerk
|
|
@@ -145,15 +145,18 @@ files:
|
|
|
145
145
|
- lib/log_bench/configuration.rb
|
|
146
146
|
- lib/log_bench/configuration_validator.rb
|
|
147
147
|
- lib/log_bench/current.rb
|
|
148
|
+
- lib/log_bench/job_prefix_formatter.rb
|
|
148
149
|
- lib/log_bench/json_formatter.rb
|
|
149
150
|
- lib/log_bench/log/call_line_entry.rb
|
|
150
151
|
- lib/log_bench/log/collection.rb
|
|
151
152
|
- lib/log_bench/log/entry.rb
|
|
152
153
|
- lib/log_bench/log/file.rb
|
|
154
|
+
- lib/log_bench/log/job_enqueue_entry.rb
|
|
153
155
|
- lib/log_bench/log/parser.rb
|
|
154
156
|
- lib/log_bench/log/query_entry.rb
|
|
155
157
|
- lib/log_bench/log/request.rb
|
|
156
158
|
- lib/log_bench/railtie.rb
|
|
159
|
+
- lib/log_bench/sidekiq_middleware.rb
|
|
157
160
|
- lib/log_bench/version.rb
|
|
158
161
|
- lib/log_bench/version_checker.rb
|
|
159
162
|
- lib/tasks/log_bench.rake
|