brainzlab 0.1.3 → 0.1.4
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/lib/brainzlab/configuration.rb +20 -0
- data/lib/brainzlab/instrumentation/action_cable.rb +351 -0
- data/lib/brainzlab/instrumentation/action_controller.rb +649 -0
- data/lib/brainzlab/instrumentation/action_dispatch.rb +259 -0
- data/lib/brainzlab/instrumentation/action_mailbox.rb +197 -0
- data/lib/brainzlab/instrumentation/action_view.rb +380 -0
- data/lib/brainzlab/instrumentation/active_job.rb +569 -0
- data/lib/brainzlab/instrumentation/active_record.rb +458 -25
- data/lib/brainzlab/instrumentation/active_storage.rb +541 -0
- data/lib/brainzlab/instrumentation/active_support_cache.rb +700 -0
- data/lib/brainzlab/instrumentation/rails_deprecation.rb +139 -0
- data/lib/brainzlab/instrumentation/railties.rb +134 -0
- data/lib/brainzlab/instrumentation.rb +91 -1
- data/lib/brainzlab/version.rb +1 -1
- metadata +11 -1
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BrainzLab
|
|
4
|
+
module Instrumentation
|
|
5
|
+
class ActiveStorage
|
|
6
|
+
# Thresholds for slow operations (in milliseconds)
|
|
7
|
+
SLOW_OPERATION_THRESHOLD = 500
|
|
8
|
+
VERY_SLOW_OPERATION_THRESHOLD = 2000
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def install!
|
|
12
|
+
return unless defined?(::ActiveStorage)
|
|
13
|
+
return if @installed
|
|
14
|
+
|
|
15
|
+
# Core Active Storage events
|
|
16
|
+
install_preview_subscriber!
|
|
17
|
+
install_transform_subscriber!
|
|
18
|
+
install_analyze_subscriber!
|
|
19
|
+
|
|
20
|
+
# Storage service events
|
|
21
|
+
install_service_upload_subscriber!
|
|
22
|
+
install_service_download_subscriber!
|
|
23
|
+
install_service_streaming_download_subscriber!
|
|
24
|
+
install_service_delete_subscriber!
|
|
25
|
+
install_service_delete_prefixed_subscriber!
|
|
26
|
+
install_service_exist_subscriber!
|
|
27
|
+
install_service_url_subscriber!
|
|
28
|
+
install_service_download_chunk_subscriber!
|
|
29
|
+
install_service_update_metadata_subscriber!
|
|
30
|
+
|
|
31
|
+
@installed = true
|
|
32
|
+
BrainzLab.debug_log('ActiveStorage instrumentation installed')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def installed?
|
|
36
|
+
@installed == true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# ============================================
|
|
42
|
+
# Preview (generating previews for files)
|
|
43
|
+
# ============================================
|
|
44
|
+
def install_preview_subscriber!
|
|
45
|
+
ActiveSupport::Notifications.subscribe('preview.active_storage') do |*args|
|
|
46
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
47
|
+
handle_preview(event)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def handle_preview(event)
|
|
52
|
+
payload = event.payload
|
|
53
|
+
duration = event.duration.round(2)
|
|
54
|
+
|
|
55
|
+
key = payload[:key]
|
|
56
|
+
|
|
57
|
+
# Record breadcrumb
|
|
58
|
+
record_storage_breadcrumb('preview', key, duration)
|
|
59
|
+
|
|
60
|
+
# Add Pulse span
|
|
61
|
+
record_storage_span(event, 'preview', key, duration)
|
|
62
|
+
|
|
63
|
+
# Log slow operations
|
|
64
|
+
log_slow_operation('preview', key, duration) if duration >= SLOW_OPERATION_THRESHOLD
|
|
65
|
+
rescue StandardError => e
|
|
66
|
+
BrainzLab.debug_log("ActiveStorage preview instrumentation failed: #{e.message}")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# ============================================
|
|
70
|
+
# Transform (image transformations)
|
|
71
|
+
# ============================================
|
|
72
|
+
def install_transform_subscriber!
|
|
73
|
+
ActiveSupport::Notifications.subscribe('transform.active_storage') do |*args|
|
|
74
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
75
|
+
handle_transform(event)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def handle_transform(event)
|
|
80
|
+
payload = event.payload
|
|
81
|
+
duration = event.duration.round(2)
|
|
82
|
+
|
|
83
|
+
key = payload[:key]
|
|
84
|
+
|
|
85
|
+
# Record breadcrumb
|
|
86
|
+
record_storage_breadcrumb('transform', key, duration)
|
|
87
|
+
|
|
88
|
+
# Add Pulse span
|
|
89
|
+
record_storage_span(event, 'transform', key, duration)
|
|
90
|
+
|
|
91
|
+
# Log slow operations
|
|
92
|
+
log_slow_operation('transform', key, duration) if duration >= SLOW_OPERATION_THRESHOLD
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
BrainzLab.debug_log("ActiveStorage transform instrumentation failed: #{e.message}")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# ============================================
|
|
98
|
+
# Analyze (file analysis - dimensions, duration, etc.)
|
|
99
|
+
# ============================================
|
|
100
|
+
def install_analyze_subscriber!
|
|
101
|
+
ActiveSupport::Notifications.subscribe('analyze.active_storage') do |*args|
|
|
102
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
103
|
+
handle_analyze(event)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def handle_analyze(event)
|
|
108
|
+
payload = event.payload
|
|
109
|
+
duration = event.duration.round(2)
|
|
110
|
+
|
|
111
|
+
analyzer = payload[:analyzer]
|
|
112
|
+
|
|
113
|
+
# Record breadcrumb
|
|
114
|
+
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
115
|
+
BrainzLab::Reflex.add_breadcrumb(
|
|
116
|
+
"Storage analyze: #{analyzer} (#{duration}ms)",
|
|
117
|
+
category: 'storage.analyze',
|
|
118
|
+
level: duration >= SLOW_OPERATION_THRESHOLD ? :warning : :info,
|
|
119
|
+
data: {
|
|
120
|
+
analyzer: analyzer,
|
|
121
|
+
duration_ms: duration
|
|
122
|
+
}.compact
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Add Pulse span
|
|
127
|
+
record_storage_span(event, 'analyze', analyzer, duration, analyzer: analyzer)
|
|
128
|
+
rescue StandardError => e
|
|
129
|
+
BrainzLab.debug_log("ActiveStorage analyze instrumentation failed: #{e.message}")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# ============================================
|
|
133
|
+
# Service Upload
|
|
134
|
+
# ============================================
|
|
135
|
+
def install_service_upload_subscriber!
|
|
136
|
+
ActiveSupport::Notifications.subscribe('service_upload.active_storage') do |*args|
|
|
137
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
138
|
+
handle_service_upload(event)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def handle_service_upload(event)
|
|
143
|
+
payload = event.payload
|
|
144
|
+
duration = event.duration.round(2)
|
|
145
|
+
|
|
146
|
+
key = payload[:key]
|
|
147
|
+
service = payload[:service]
|
|
148
|
+
checksum = payload[:checksum]
|
|
149
|
+
|
|
150
|
+
# Record breadcrumb
|
|
151
|
+
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
152
|
+
level = case duration
|
|
153
|
+
when 0...SLOW_OPERATION_THRESHOLD then :info
|
|
154
|
+
when SLOW_OPERATION_THRESHOLD...VERY_SLOW_OPERATION_THRESHOLD then :warning
|
|
155
|
+
else :error
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
BrainzLab::Reflex.add_breadcrumb(
|
|
159
|
+
"Storage upload: #{truncate_key(key)} (#{duration}ms)",
|
|
160
|
+
category: 'storage.upload',
|
|
161
|
+
level: level,
|
|
162
|
+
data: {
|
|
163
|
+
key: truncate_key(key),
|
|
164
|
+
service: service,
|
|
165
|
+
duration_ms: duration
|
|
166
|
+
}.compact
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Add Pulse span
|
|
171
|
+
record_service_span(event, 'upload', key, duration, service: service)
|
|
172
|
+
|
|
173
|
+
# Log slow uploads
|
|
174
|
+
log_slow_operation('upload', key, duration, service: service) if duration >= SLOW_OPERATION_THRESHOLD
|
|
175
|
+
rescue StandardError => e
|
|
176
|
+
BrainzLab.debug_log("ActiveStorage service_upload instrumentation failed: #{e.message}")
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# ============================================
|
|
180
|
+
# Service Download
|
|
181
|
+
# ============================================
|
|
182
|
+
def install_service_download_subscriber!
|
|
183
|
+
ActiveSupport::Notifications.subscribe('service_download.active_storage') do |*args|
|
|
184
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
185
|
+
handle_service_download(event)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def handle_service_download(event)
|
|
190
|
+
payload = event.payload
|
|
191
|
+
duration = event.duration.round(2)
|
|
192
|
+
|
|
193
|
+
key = payload[:key]
|
|
194
|
+
service = payload[:service]
|
|
195
|
+
|
|
196
|
+
# Record breadcrumb
|
|
197
|
+
record_storage_breadcrumb('download', key, duration, service: service)
|
|
198
|
+
|
|
199
|
+
# Add Pulse span
|
|
200
|
+
record_service_span(event, 'download', key, duration, service: service)
|
|
201
|
+
|
|
202
|
+
# Log slow downloads
|
|
203
|
+
log_slow_operation('download', key, duration, service: service) if duration >= SLOW_OPERATION_THRESHOLD
|
|
204
|
+
rescue StandardError => e
|
|
205
|
+
BrainzLab.debug_log("ActiveStorage service_download instrumentation failed: #{e.message}")
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# ============================================
|
|
209
|
+
# Service Streaming Download
|
|
210
|
+
# ============================================
|
|
211
|
+
def install_service_streaming_download_subscriber!
|
|
212
|
+
ActiveSupport::Notifications.subscribe('service_streaming_download.active_storage') do |*args|
|
|
213
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
214
|
+
handle_service_streaming_download(event)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def handle_service_streaming_download(event)
|
|
219
|
+
payload = event.payload
|
|
220
|
+
duration = event.duration.round(2)
|
|
221
|
+
|
|
222
|
+
key = payload[:key]
|
|
223
|
+
service = payload[:service]
|
|
224
|
+
|
|
225
|
+
# Record breadcrumb
|
|
226
|
+
record_storage_breadcrumb('streaming_download', key, duration, service: service)
|
|
227
|
+
|
|
228
|
+
# Add Pulse span
|
|
229
|
+
record_service_span(event, 'streaming_download', key, duration, service: service)
|
|
230
|
+
rescue StandardError => e
|
|
231
|
+
BrainzLab.debug_log("ActiveStorage service_streaming_download instrumentation failed: #{e.message}")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# ============================================
|
|
235
|
+
# Service Delete
|
|
236
|
+
# ============================================
|
|
237
|
+
def install_service_delete_subscriber!
|
|
238
|
+
ActiveSupport::Notifications.subscribe('service_delete.active_storage') do |*args|
|
|
239
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
240
|
+
handle_service_delete(event)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def handle_service_delete(event)
|
|
245
|
+
payload = event.payload
|
|
246
|
+
duration = event.duration.round(2)
|
|
247
|
+
|
|
248
|
+
key = payload[:key]
|
|
249
|
+
service = payload[:service]
|
|
250
|
+
|
|
251
|
+
# Record breadcrumb
|
|
252
|
+
record_storage_breadcrumb('delete', key, duration, service: service)
|
|
253
|
+
|
|
254
|
+
# Add Pulse span
|
|
255
|
+
record_service_span(event, 'delete', key, duration, service: service)
|
|
256
|
+
rescue StandardError => e
|
|
257
|
+
BrainzLab.debug_log("ActiveStorage service_delete instrumentation failed: #{e.message}")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# ============================================
|
|
261
|
+
# Service Delete Prefixed (bulk delete)
|
|
262
|
+
# ============================================
|
|
263
|
+
def install_service_delete_prefixed_subscriber!
|
|
264
|
+
ActiveSupport::Notifications.subscribe('service_delete_prefixed.active_storage') do |*args|
|
|
265
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
266
|
+
handle_service_delete_prefixed(event)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def handle_service_delete_prefixed(event)
|
|
271
|
+
payload = event.payload
|
|
272
|
+
duration = event.duration.round(2)
|
|
273
|
+
|
|
274
|
+
prefix = payload[:prefix]
|
|
275
|
+
service = payload[:service]
|
|
276
|
+
|
|
277
|
+
# Record breadcrumb
|
|
278
|
+
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
279
|
+
BrainzLab::Reflex.add_breadcrumb(
|
|
280
|
+
"Storage delete prefixed: #{truncate_key(prefix)}* (#{duration}ms)",
|
|
281
|
+
category: 'storage.delete_prefixed',
|
|
282
|
+
level: :warning,
|
|
283
|
+
data: {
|
|
284
|
+
prefix: truncate_key(prefix),
|
|
285
|
+
service: service,
|
|
286
|
+
duration_ms: duration
|
|
287
|
+
}.compact
|
|
288
|
+
)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Add Pulse span
|
|
292
|
+
record_service_span(event, 'delete_prefixed', prefix, duration, service: service)
|
|
293
|
+
|
|
294
|
+
# Log to Recall - bulk deletes are significant
|
|
295
|
+
if BrainzLab.configuration.recall_effectively_enabled?
|
|
296
|
+
BrainzLab::Recall.info(
|
|
297
|
+
"Storage bulk delete by prefix",
|
|
298
|
+
prefix: truncate_key(prefix),
|
|
299
|
+
service: service,
|
|
300
|
+
duration_ms: duration
|
|
301
|
+
)
|
|
302
|
+
end
|
|
303
|
+
rescue StandardError => e
|
|
304
|
+
BrainzLab.debug_log("ActiveStorage service_delete_prefixed instrumentation failed: #{e.message}")
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# ============================================
|
|
308
|
+
# Service Exist
|
|
309
|
+
# ============================================
|
|
310
|
+
def install_service_exist_subscriber!
|
|
311
|
+
ActiveSupport::Notifications.subscribe('service_exist.active_storage') do |*args|
|
|
312
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
313
|
+
handle_service_exist(event)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def handle_service_exist(event)
|
|
318
|
+
payload = event.payload
|
|
319
|
+
duration = event.duration.round(2)
|
|
320
|
+
|
|
321
|
+
key = payload[:key]
|
|
322
|
+
service = payload[:service]
|
|
323
|
+
exist = payload[:exist]
|
|
324
|
+
|
|
325
|
+
# Only track if slow (existence checks are frequent)
|
|
326
|
+
return if duration < 5
|
|
327
|
+
|
|
328
|
+
# Add Pulse span
|
|
329
|
+
record_service_span(event, 'exist', key, duration, service: service, exist: exist)
|
|
330
|
+
rescue StandardError => e
|
|
331
|
+
BrainzLab.debug_log("ActiveStorage service_exist instrumentation failed: #{e.message}")
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# ============================================
|
|
335
|
+
# Service URL (generating signed URLs)
|
|
336
|
+
# ============================================
|
|
337
|
+
def install_service_url_subscriber!
|
|
338
|
+
ActiveSupport::Notifications.subscribe('service_url.active_storage') do |*args|
|
|
339
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
340
|
+
handle_service_url(event)
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def handle_service_url(event)
|
|
345
|
+
payload = event.payload
|
|
346
|
+
duration = event.duration.round(2)
|
|
347
|
+
|
|
348
|
+
key = payload[:key]
|
|
349
|
+
service = payload[:service]
|
|
350
|
+
|
|
351
|
+
# Only track if slow (URL generation should be fast)
|
|
352
|
+
return if duration < 10
|
|
353
|
+
|
|
354
|
+
# Add Pulse span for slow URL generations
|
|
355
|
+
record_service_span(event, 'url', key, duration, service: service)
|
|
356
|
+
|
|
357
|
+
# Log slow URL generations
|
|
358
|
+
if duration >= 50 && BrainzLab.configuration.recall_effectively_enabled?
|
|
359
|
+
BrainzLab::Recall.warn(
|
|
360
|
+
"Slow storage URL generation",
|
|
361
|
+
key: truncate_key(key),
|
|
362
|
+
service: service,
|
|
363
|
+
duration_ms: duration
|
|
364
|
+
)
|
|
365
|
+
end
|
|
366
|
+
rescue StandardError => e
|
|
367
|
+
BrainzLab.debug_log("ActiveStorage service_url instrumentation failed: #{e.message}")
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# ============================================
|
|
371
|
+
# Service Download Chunk (chunked downloads)
|
|
372
|
+
# ============================================
|
|
373
|
+
def install_service_download_chunk_subscriber!
|
|
374
|
+
ActiveSupport::Notifications.subscribe('service_download_chunk.active_storage') do |*args|
|
|
375
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
376
|
+
handle_service_download_chunk(event)
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def handle_service_download_chunk(event)
|
|
381
|
+
payload = event.payload
|
|
382
|
+
duration = event.duration.round(2)
|
|
383
|
+
|
|
384
|
+
key = payload[:key]
|
|
385
|
+
service = payload[:service]
|
|
386
|
+
range = payload[:range]
|
|
387
|
+
|
|
388
|
+
# Only track slow chunks
|
|
389
|
+
return if duration < 10
|
|
390
|
+
|
|
391
|
+
# Add Pulse span for slow chunk downloads
|
|
392
|
+
record_service_span(event, 'download_chunk', key, duration, service: service, range: range.to_s)
|
|
393
|
+
rescue StandardError => e
|
|
394
|
+
BrainzLab.debug_log("ActiveStorage service_download_chunk instrumentation failed: #{e.message}")
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# ============================================
|
|
398
|
+
# Service Update Metadata
|
|
399
|
+
# ============================================
|
|
400
|
+
def install_service_update_metadata_subscriber!
|
|
401
|
+
ActiveSupport::Notifications.subscribe('service_update_metadata.active_storage') do |*args|
|
|
402
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
403
|
+
handle_service_update_metadata(event)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def handle_service_update_metadata(event)
|
|
408
|
+
payload = event.payload
|
|
409
|
+
duration = event.duration.round(2)
|
|
410
|
+
|
|
411
|
+
key = payload[:key]
|
|
412
|
+
service = payload[:service]
|
|
413
|
+
content_type = payload[:content_type]
|
|
414
|
+
disposition = payload[:disposition]
|
|
415
|
+
|
|
416
|
+
# Record breadcrumb
|
|
417
|
+
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
418
|
+
BrainzLab::Reflex.add_breadcrumb(
|
|
419
|
+
"Storage metadata update: #{truncate_key(key)} (#{duration}ms)",
|
|
420
|
+
category: 'storage.metadata',
|
|
421
|
+
level: :info,
|
|
422
|
+
data: {
|
|
423
|
+
key: truncate_key(key),
|
|
424
|
+
service: service,
|
|
425
|
+
content_type: content_type,
|
|
426
|
+
duration_ms: duration
|
|
427
|
+
}.compact
|
|
428
|
+
)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# Add Pulse span
|
|
432
|
+
record_service_span(event, 'update_metadata', key, duration,
|
|
433
|
+
service: service, content_type: content_type)
|
|
434
|
+
rescue StandardError => e
|
|
435
|
+
BrainzLab.debug_log("ActiveStorage service_update_metadata instrumentation failed: #{e.message}")
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
# ============================================
|
|
439
|
+
# Recording Helpers
|
|
440
|
+
# ============================================
|
|
441
|
+
def record_storage_breadcrumb(operation, key, duration, service: nil)
|
|
442
|
+
return unless BrainzLab.configuration.reflex_effectively_enabled?
|
|
443
|
+
|
|
444
|
+
level = case duration
|
|
445
|
+
when 0...SLOW_OPERATION_THRESHOLD then :info
|
|
446
|
+
when SLOW_OPERATION_THRESHOLD...VERY_SLOW_OPERATION_THRESHOLD then :warning
|
|
447
|
+
else :error
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
BrainzLab::Reflex.add_breadcrumb(
|
|
451
|
+
"Storage #{operation}: #{truncate_key(key)} (#{duration}ms)",
|
|
452
|
+
category: "storage.#{operation}",
|
|
453
|
+
level: level,
|
|
454
|
+
data: {
|
|
455
|
+
key: truncate_key(key),
|
|
456
|
+
service: service,
|
|
457
|
+
duration_ms: duration
|
|
458
|
+
}.compact
|
|
459
|
+
)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
def record_storage_span(event, operation, key, duration, **extra)
|
|
463
|
+
return unless BrainzLab.configuration.pulse_effectively_enabled?
|
|
464
|
+
|
|
465
|
+
tracer = BrainzLab::Pulse.tracer
|
|
466
|
+
return unless tracer.current_trace
|
|
467
|
+
|
|
468
|
+
span_data = {
|
|
469
|
+
span_id: SecureRandom.uuid,
|
|
470
|
+
name: "storage.#{operation}",
|
|
471
|
+
kind: 'storage',
|
|
472
|
+
started_at: event.time,
|
|
473
|
+
ended_at: event.end,
|
|
474
|
+
duration_ms: duration,
|
|
475
|
+
error: false,
|
|
476
|
+
data: {
|
|
477
|
+
'storage.operation' => operation,
|
|
478
|
+
'storage.key' => truncate_key(key)
|
|
479
|
+
}.merge(extra.transform_keys { |k| "storage.#{k}" }).compact
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
tracer.current_spans << span_data
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def record_service_span(event, operation, key, duration, service: nil, **extra)
|
|
486
|
+
return unless BrainzLab.configuration.pulse_effectively_enabled?
|
|
487
|
+
|
|
488
|
+
tracer = BrainzLab::Pulse.tracer
|
|
489
|
+
return unless tracer.current_trace
|
|
490
|
+
|
|
491
|
+
span_data = {
|
|
492
|
+
span_id: SecureRandom.uuid,
|
|
493
|
+
name: "storage.service.#{operation}",
|
|
494
|
+
kind: 'storage',
|
|
495
|
+
started_at: event.time,
|
|
496
|
+
ended_at: event.end,
|
|
497
|
+
duration_ms: duration,
|
|
498
|
+
error: false,
|
|
499
|
+
data: {
|
|
500
|
+
'storage.operation' => operation,
|
|
501
|
+
'storage.key' => truncate_key(key),
|
|
502
|
+
'storage.service' => service
|
|
503
|
+
}.merge(extra.transform_keys { |k| "storage.#{k}" }).compact
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
tracer.current_spans << span_data
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def log_slow_operation(operation, key, duration, service: nil)
|
|
510
|
+
return unless BrainzLab.configuration.recall_effectively_enabled?
|
|
511
|
+
|
|
512
|
+
level = duration >= VERY_SLOW_OPERATION_THRESHOLD ? :error : :warn
|
|
513
|
+
|
|
514
|
+
BrainzLab::Recall.send(
|
|
515
|
+
level,
|
|
516
|
+
"Slow storage #{operation}: #{truncate_key(key)} (#{duration}ms)",
|
|
517
|
+
operation: operation,
|
|
518
|
+
key: truncate_key(key),
|
|
519
|
+
service: service,
|
|
520
|
+
duration_ms: duration,
|
|
521
|
+
threshold_exceeded: duration >= VERY_SLOW_OPERATION_THRESHOLD ? 'critical' : 'warning'
|
|
522
|
+
)
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# ============================================
|
|
526
|
+
# Helper Methods
|
|
527
|
+
# ============================================
|
|
528
|
+
def truncate_key(key, max_length = 100)
|
|
529
|
+
return 'unknown' unless key
|
|
530
|
+
|
|
531
|
+
key_str = key.to_s
|
|
532
|
+
if key_str.length > max_length
|
|
533
|
+
"#{key_str[0, max_length - 3]}..."
|
|
534
|
+
else
|
|
535
|
+
key_str
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
end
|