brainzlab 0.1.2 → 0.1.3
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/LICENSE +6 -21
- data/README.md +16 -2
- data/lib/brainzlab/beacon/client.rb +38 -40
- data/lib/brainzlab/beacon/provisioner.rb +1 -1
- data/lib/brainzlab/beacon.rb +15 -15
- data/lib/brainzlab/configuration.rb +92 -90
- data/lib/brainzlab/context.rb +2 -3
- data/lib/brainzlab/cortex/client.rb +29 -31
- data/lib/brainzlab/cortex/provisioner.rb +1 -1
- data/lib/brainzlab/cortex.rb +7 -11
- data/lib/brainzlab/dendrite/client.rb +42 -44
- data/lib/brainzlab/dendrite/provisioner.rb +1 -1
- data/lib/brainzlab/dendrite.rb +4 -4
- data/lib/brainzlab/devtools/data/collector.rb +22 -22
- data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
- data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
- data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
- data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
- data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
- data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
- data/lib/brainzlab/devtools.rb +11 -11
- data/lib/brainzlab/flux/buffer.rb +3 -3
- data/lib/brainzlab/flux/client.rb +14 -16
- data/lib/brainzlab/flux/provisioner.rb +13 -13
- data/lib/brainzlab/flux.rb +8 -8
- data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
- data/lib/brainzlab/instrumentation/active_record.rb +13 -15
- data/lib/brainzlab/instrumentation/aws.rb +43 -39
- data/lib/brainzlab/instrumentation/dalli.rb +20 -20
- data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
- data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
- data/lib/brainzlab/instrumentation/excon.rb +27 -27
- data/lib/brainzlab/instrumentation/faraday.rb +3 -4
- data/lib/brainzlab/instrumentation/good_job.rb +28 -28
- data/lib/brainzlab/instrumentation/grape.rb +24 -24
- data/lib/brainzlab/instrumentation/graphql.rb +24 -23
- data/lib/brainzlab/instrumentation/httparty.rb +13 -14
- data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
- data/lib/brainzlab/instrumentation/net_http.rb +6 -6
- data/lib/brainzlab/instrumentation/redis.rb +14 -21
- data/lib/brainzlab/instrumentation/resque.rb +23 -24
- data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
- data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
- data/lib/brainzlab/instrumentation/stripe.rb +36 -37
- data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
- data/lib/brainzlab/instrumentation.rb +20 -20
- data/lib/brainzlab/nerve/client.rb +38 -40
- data/lib/brainzlab/nerve/provisioner.rb +1 -1
- data/lib/brainzlab/nerve.rb +6 -6
- data/lib/brainzlab/pulse/client.rb +15 -11
- data/lib/brainzlab/pulse/instrumentation.rb +61 -57
- data/lib/brainzlab/pulse/propagation.rb +28 -28
- data/lib/brainzlab/pulse/provisioner.rb +12 -12
- data/lib/brainzlab/pulse/tracer.rb +3 -3
- data/lib/brainzlab/pulse.rb +13 -13
- data/lib/brainzlab/rails/log_formatter.rb +127 -121
- data/lib/brainzlab/rails/log_subscriber.rb +70 -76
- data/lib/brainzlab/rails/railtie.rb +66 -89
- data/lib/brainzlab/recall/buffer.rb +1 -1
- data/lib/brainzlab/recall/client.rb +14 -10
- data/lib/brainzlab/recall/logger.rb +16 -18
- data/lib/brainzlab/recall/provisioner.rb +16 -16
- data/lib/brainzlab/recall.rb +11 -13
- data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
- data/lib/brainzlab/reflex/client.rb +14 -10
- data/lib/brainzlab/reflex/provisioner.rb +12 -12
- data/lib/brainzlab/reflex.rb +29 -29
- data/lib/brainzlab/sentinel/client.rb +40 -42
- data/lib/brainzlab/sentinel/provisioner.rb +1 -1
- data/lib/brainzlab/sentinel.rb +5 -5
- data/lib/brainzlab/signal/client.rb +12 -14
- data/lib/brainzlab/signal/provisioner.rb +12 -12
- data/lib/brainzlab/signal.rb +7 -7
- data/lib/brainzlab/synapse/client.rb +42 -44
- data/lib/brainzlab/synapse/provisioner.rb +1 -1
- data/lib/brainzlab/synapse.rb +6 -6
- data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
- data/lib/brainzlab/utilities/health_check.rb +53 -55
- data/lib/brainzlab/utilities/log_formatter.rb +38 -40
- data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
- data/lib/brainzlab/utilities.rb +4 -4
- data/lib/brainzlab/vault/cache.rb +1 -1
- data/lib/brainzlab/vault/client.rb +39 -41
- data/lib/brainzlab/vault/provisioner.rb +1 -1
- data/lib/brainzlab/vault.rb +19 -25
- data/lib/brainzlab/version.rb +1 -1
- data/lib/brainzlab/vision/client.rb +20 -20
- data/lib/brainzlab/vision/provisioner.rb +21 -21
- data/lib/brainzlab/vision.rb +17 -19
- data/lib/brainzlab-sdk.rb +1 -1
- data/lib/brainzlab.rb +22 -24
- data/lib/generators/brainzlab/install/install_generator.rb +29 -27
- metadata +1 -1
|
@@ -29,7 +29,7 @@ module BrainzLab
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
@installed = true
|
|
32
|
-
BrainzLab.debug_log(
|
|
32
|
+
BrainzLab.debug_log('Sidekiq instrumentation installed')
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def installed?
|
|
@@ -47,11 +47,11 @@ module BrainzLab
|
|
|
47
47
|
return yield unless should_trace?
|
|
48
48
|
|
|
49
49
|
started_at = Time.now.utc
|
|
50
|
-
job_class = job[
|
|
51
|
-
job_id = job[
|
|
50
|
+
job_class = job['class'] || worker.class.name
|
|
51
|
+
job_id = job['jid']
|
|
52
52
|
|
|
53
53
|
# Calculate queue wait time
|
|
54
|
-
enqueued_at = job[
|
|
54
|
+
enqueued_at = job['enqueued_at'] ? Time.at(job['enqueued_at']) : nil
|
|
55
55
|
queue_wait_ms = enqueued_at ? ((started_at - enqueued_at) * 1000).round(2) : nil
|
|
56
56
|
|
|
57
57
|
# Extract parent trace context if present (distributed tracing)
|
|
@@ -63,9 +63,9 @@ module BrainzLab
|
|
|
63
63
|
# Add breadcrumb
|
|
64
64
|
BrainzLab::Reflex.add_breadcrumb(
|
|
65
65
|
"Sidekiq #{job_class}",
|
|
66
|
-
category:
|
|
66
|
+
category: 'job.sidekiq',
|
|
67
67
|
level: :info,
|
|
68
|
-
data: { job_id: job_id, queue: queue, retry_count: job[
|
|
68
|
+
data: { job_id: job_id, queue: queue, retry_count: job['retry_count'] }
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
# Initialize Pulse tracing
|
|
@@ -85,7 +85,7 @@ module BrainzLab
|
|
|
85
85
|
queue: queue,
|
|
86
86
|
started_at: started_at,
|
|
87
87
|
queue_wait_ms: queue_wait_ms,
|
|
88
|
-
retry_count: job[
|
|
88
|
+
retry_count: job['retry_count'] || 0,
|
|
89
89
|
parent_context: parent_context,
|
|
90
90
|
error: error_occurred
|
|
91
91
|
)
|
|
@@ -102,11 +102,11 @@ module BrainzLab
|
|
|
102
102
|
|
|
103
103
|
def setup_context(job, queue)
|
|
104
104
|
BrainzLab::Context.current.set_context(
|
|
105
|
-
job_class: job[
|
|
106
|
-
job_id: job[
|
|
105
|
+
job_class: job['class'],
|
|
106
|
+
job_id: job['jid'],
|
|
107
107
|
queue_name: queue,
|
|
108
|
-
retry_count: job[
|
|
109
|
-
arguments: job[
|
|
108
|
+
retry_count: job['retry_count'],
|
|
109
|
+
arguments: job['args']&.map(&:to_s)&.first(5)
|
|
110
110
|
)
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -118,19 +118,20 @@ module BrainzLab
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def extract_trace_context(job)
|
|
121
|
-
return nil unless job[
|
|
121
|
+
return nil unless job['_brainzlab_trace']
|
|
122
122
|
|
|
123
|
-
trace_data = job[
|
|
123
|
+
trace_data = job['_brainzlab_trace']
|
|
124
124
|
BrainzLab::Pulse::Propagation::Context.new(
|
|
125
|
-
trace_id: trace_data[
|
|
126
|
-
span_id: trace_data[
|
|
127
|
-
sampled: trace_data[
|
|
125
|
+
trace_id: trace_data['trace_id'],
|
|
126
|
+
span_id: trace_data['span_id'],
|
|
127
|
+
sampled: trace_data['sampled'] != false
|
|
128
128
|
)
|
|
129
129
|
rescue StandardError
|
|
130
130
|
nil
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
def record_trace(job_class:, job_id:, queue:, started_at:, queue_wait_ms:, retry_count:, parent_context:,
|
|
133
|
+
def record_trace(job_class:, job_id:, queue:, started_at:, queue_wait_ms:, retry_count:, parent_context:,
|
|
134
|
+
error:)
|
|
134
135
|
ended_at = Time.now.utc
|
|
135
136
|
duration_ms = ((ended_at - started_at) * 1000).round(2)
|
|
136
137
|
|
|
@@ -156,7 +157,7 @@ module BrainzLab
|
|
|
156
157
|
payload = {
|
|
157
158
|
trace_id: SecureRandom.uuid,
|
|
158
159
|
name: job_class,
|
|
159
|
-
kind:
|
|
160
|
+
kind: 'job',
|
|
160
161
|
started_at: started_at.utc.iso8601(3),
|
|
161
162
|
ended_at: ended_at.utc.iso8601(3),
|
|
162
163
|
duration_ms: duration_ms,
|
|
@@ -200,7 +201,7 @@ module BrainzLab
|
|
|
200
201
|
|
|
201
202
|
# Client middleware - runs when jobs are enqueued
|
|
202
203
|
class ClientMiddleware
|
|
203
|
-
def call(
|
|
204
|
+
def call(_worker_class, job, queue, _redis_pool)
|
|
204
205
|
# Inject trace context for distributed tracing
|
|
205
206
|
inject_trace_context(job)
|
|
206
207
|
|
|
@@ -208,9 +209,9 @@ module BrainzLab
|
|
|
208
209
|
if BrainzLab.configuration.reflex_enabled
|
|
209
210
|
BrainzLab::Reflex.add_breadcrumb(
|
|
210
211
|
"Enqueue #{job['class']}",
|
|
211
|
-
category:
|
|
212
|
+
category: 'job.sidekiq.enqueue',
|
|
212
213
|
level: :info,
|
|
213
|
-
data: { queue: queue, job_id: job[
|
|
214
|
+
data: { queue: queue, job_id: job['jid'] }
|
|
214
215
|
)
|
|
215
216
|
end
|
|
216
217
|
|
|
@@ -231,10 +232,10 @@ module BrainzLab
|
|
|
231
232
|
|
|
232
233
|
return unless ctx&.valid?
|
|
233
234
|
|
|
234
|
-
job[
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
job['_brainzlab_trace'] = {
|
|
236
|
+
'trace_id' => ctx.trace_id,
|
|
237
|
+
'span_id' => ctx.span_id,
|
|
238
|
+
'sampled' => ctx.sampled
|
|
238
239
|
}
|
|
239
240
|
rescue StandardError => e
|
|
240
241
|
BrainzLab.debug_log("Failed to inject Sidekiq trace context: #{e.message}")
|
|
@@ -247,13 +248,13 @@ module BrainzLab
|
|
|
247
248
|
spans << {
|
|
248
249
|
span_id: SecureRandom.uuid,
|
|
249
250
|
name: "Enqueue #{job['class']}",
|
|
250
|
-
kind:
|
|
251
|
+
kind: 'job',
|
|
251
252
|
started_at: Time.now.utc,
|
|
252
253
|
ended_at: Time.now.utc,
|
|
253
254
|
duration_ms: 0,
|
|
254
255
|
data: {
|
|
255
|
-
job_class: job[
|
|
256
|
-
job_id: job[
|
|
256
|
+
job_class: job['class'],
|
|
257
|
+
job_id: job['jid'],
|
|
257
258
|
queue: queue
|
|
258
259
|
}
|
|
259
260
|
}
|
|
@@ -10,7 +10,7 @@ module BrainzLab
|
|
|
10
10
|
install_job_instrumentation!
|
|
11
11
|
install_worker_instrumentation!
|
|
12
12
|
|
|
13
|
-
BrainzLab.debug_log(
|
|
13
|
+
BrainzLab.debug_log('[Instrumentation] SolidQueue instrumentation installed')
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
private
|
|
@@ -31,10 +31,10 @@ module BrainzLab
|
|
|
31
31
|
|
|
32
32
|
def install_worker_instrumentation!
|
|
33
33
|
# Subscribe to ActiveSupport notifications for SolidQueue
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
return unless defined?(::ActiveSupport::Notifications)
|
|
35
|
+
|
|
36
|
+
::ActiveSupport::Notifications.subscribe(/solid_queue/) do |name, start, finish, _id, payload|
|
|
37
|
+
handle_notification(name, start, finish, payload)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -42,26 +42,26 @@ module BrainzLab
|
|
|
42
42
|
duration_ms = ((finish - start) * 1000).round(2)
|
|
43
43
|
|
|
44
44
|
case name
|
|
45
|
-
when
|
|
45
|
+
when 'perform.solid_queue'
|
|
46
46
|
track_job_perform(payload, duration_ms)
|
|
47
|
-
when
|
|
47
|
+
when 'enqueue.solid_queue'
|
|
48
48
|
track_job_enqueue(payload)
|
|
49
|
-
when
|
|
49
|
+
when 'discard.solid_queue'
|
|
50
50
|
track_job_discard(payload)
|
|
51
|
-
when
|
|
51
|
+
when 'retry.solid_queue'
|
|
52
52
|
track_job_retry(payload)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def track_job_perform(payload, duration_ms)
|
|
57
57
|
job_class = payload[:job]&.class&.name || payload[:job_class]
|
|
58
|
-
queue = payload[:queue] ||
|
|
58
|
+
queue = payload[:queue] || 'default'
|
|
59
59
|
|
|
60
60
|
# Track with Pulse
|
|
61
61
|
if BrainzLab.configuration.pulse_effectively_enabled?
|
|
62
62
|
BrainzLab::Pulse.record_trace(
|
|
63
63
|
"job.#{job_class}",
|
|
64
|
-
kind:
|
|
64
|
+
kind: 'job',
|
|
65
65
|
started_at: Time.now - (duration_ms / 1000.0),
|
|
66
66
|
ended_at: Time.now,
|
|
67
67
|
job_class: job_class,
|
|
@@ -77,18 +77,16 @@ module BrainzLab
|
|
|
77
77
|
# Track with Flux
|
|
78
78
|
if BrainzLab.configuration.flux_effectively_enabled?
|
|
79
79
|
tags = { job_class: job_class, queue: queue }
|
|
80
|
-
BrainzLab::Flux.distribution(
|
|
81
|
-
BrainzLab::Flux.increment(
|
|
80
|
+
BrainzLab::Flux.distribution('solid_queue.job.duration_ms', duration_ms, tags: tags)
|
|
81
|
+
BrainzLab::Flux.increment('solid_queue.job.processed', tags: tags)
|
|
82
82
|
|
|
83
|
-
if payload[:error]
|
|
84
|
-
BrainzLab::Flux.increment("solid_queue.job.failed", tags: tags)
|
|
85
|
-
end
|
|
83
|
+
BrainzLab::Flux.increment('solid_queue.job.failed', tags: tags) if payload[:error]
|
|
86
84
|
end
|
|
87
85
|
|
|
88
86
|
# Add breadcrumb for Reflex
|
|
89
87
|
BrainzLab::Reflex.add_breadcrumb(
|
|
90
88
|
"Job #{job_class} completed in #{duration_ms}ms",
|
|
91
|
-
category:
|
|
89
|
+
category: 'job',
|
|
92
90
|
level: payload[:error] ? :error : :info,
|
|
93
91
|
data: { queue: queue, job_id: payload[:job_id], duration_ms: duration_ms }
|
|
94
92
|
)
|
|
@@ -96,33 +94,33 @@ module BrainzLab
|
|
|
96
94
|
|
|
97
95
|
def track_job_enqueue(payload)
|
|
98
96
|
job_class = payload[:job]&.class&.name || payload[:job_class]
|
|
99
|
-
queue = payload[:queue] ||
|
|
97
|
+
queue = payload[:queue] || 'default'
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
100
|
+
|
|
101
|
+
BrainzLab::Flux.increment('solid_queue.job.enqueued', tags: { job_class: job_class, queue: queue })
|
|
104
102
|
end
|
|
105
103
|
|
|
106
104
|
def track_job_discard(payload)
|
|
107
105
|
job_class = payload[:job]&.class&.name || payload[:job_class]
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
108
|
+
|
|
109
|
+
BrainzLab::Flux.increment('solid_queue.job.discarded', tags: { job_class: job_class })
|
|
112
110
|
end
|
|
113
111
|
|
|
114
112
|
def track_job_retry(payload)
|
|
115
113
|
job_class = payload[:job]&.class&.name || payload[:job_class]
|
|
116
114
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
116
|
+
|
|
117
|
+
BrainzLab::Flux.increment('solid_queue.job.retried', tags: { job_class: job_class })
|
|
120
118
|
end
|
|
121
119
|
end
|
|
122
120
|
|
|
123
121
|
def self.around_perform(job)
|
|
124
122
|
job_class = job.class.name
|
|
125
|
-
queue = job.queue_name ||
|
|
123
|
+
queue = job.queue_name || 'default'
|
|
126
124
|
started_at = Time.now
|
|
127
125
|
|
|
128
126
|
# Set context for the job
|
|
@@ -138,13 +136,12 @@ module BrainzLab
|
|
|
138
136
|
# Capture error with Reflex
|
|
139
137
|
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
140
138
|
BrainzLab::Reflex.capture(e,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
139
|
+
tags: { job_class: job_class, queue: queue },
|
|
140
|
+
extra: {
|
|
141
|
+
job_id: job.job_id,
|
|
142
|
+
arguments: safe_arguments(job),
|
|
143
|
+
executions: job.executions
|
|
144
|
+
})
|
|
148
145
|
end
|
|
149
146
|
raise
|
|
150
147
|
ensure
|
|
@@ -154,7 +151,7 @@ module BrainzLab
|
|
|
154
151
|
if BrainzLab.configuration.pulse_effectively_enabled?
|
|
155
152
|
BrainzLab::Pulse.record_trace(
|
|
156
153
|
"job.#{job_class}",
|
|
157
|
-
kind:
|
|
154
|
+
kind: 'job',
|
|
158
155
|
started_at: started_at,
|
|
159
156
|
ended_at: Time.now,
|
|
160
157
|
job_class: job_class,
|
|
@@ -167,7 +164,7 @@ module BrainzLab
|
|
|
167
164
|
# Record metrics
|
|
168
165
|
if BrainzLab.configuration.flux_effectively_enabled?
|
|
169
166
|
tags = { job_class: job_class, queue: queue }
|
|
170
|
-
BrainzLab::Flux.distribution(
|
|
167
|
+
BrainzLab::Flux.distribution('solid_queue.job.duration_ms', duration_ms, tags: tags)
|
|
171
168
|
end
|
|
172
169
|
|
|
173
170
|
# Clear context
|
|
@@ -180,9 +177,8 @@ module BrainzLab
|
|
|
180
177
|
rescue StandardError => e
|
|
181
178
|
if BrainzLab.configuration.reflex_effectively_enabled?
|
|
182
179
|
BrainzLab::Reflex.capture(e,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
)
|
|
180
|
+
tags: { job_class: job.class.name, queue: job.queue_name },
|
|
181
|
+
extra: { job_id: job.job_id, arguments: safe_arguments(job) })
|
|
186
182
|
end
|
|
187
183
|
raise
|
|
188
184
|
end
|
|
@@ -191,7 +187,7 @@ module BrainzLab
|
|
|
191
187
|
args = job.arguments
|
|
192
188
|
BrainzLab::Reflex.send(:filter_params, args) if args
|
|
193
189
|
rescue StandardError
|
|
194
|
-
|
|
190
|
+
'[Unable to serialize]'
|
|
195
191
|
end
|
|
196
192
|
end
|
|
197
193
|
end
|
|
@@ -9,7 +9,7 @@ module BrainzLab
|
|
|
9
9
|
|
|
10
10
|
install_instrumentation!
|
|
11
11
|
|
|
12
|
-
BrainzLab.debug_log(
|
|
12
|
+
BrainzLab.debug_log('[Instrumentation] Stripe instrumentation installed')
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
private
|
|
@@ -63,8 +63,8 @@ module BrainzLab
|
|
|
63
63
|
|
|
64
64
|
def extract_resource(path)
|
|
65
65
|
# /v1/customers/cus_xxx -> customers
|
|
66
|
-
parts = path.to_s.split(
|
|
67
|
-
parts[1] ||
|
|
66
|
+
parts = path.to_s.split('/').reject(&:empty?)
|
|
67
|
+
parts[1] || 'unknown'
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -73,11 +73,11 @@ module BrainzLab
|
|
|
73
73
|
def track_event(event)
|
|
74
74
|
duration_ms = (event[:duration] * 1000).round(2) if event[:duration]
|
|
75
75
|
method = event[:method].to_s.upcase
|
|
76
|
-
resource = event[:path].to_s.split(
|
|
76
|
+
resource = event[:path].to_s.split('/')[2] || 'unknown'
|
|
77
77
|
|
|
78
78
|
BrainzLab::Reflex.add_breadcrumb(
|
|
79
79
|
"Stripe #{method} #{resource}",
|
|
80
|
-
category:
|
|
80
|
+
category: 'payment',
|
|
81
81
|
level: event[:error] ? :error : :info,
|
|
82
82
|
data: {
|
|
83
83
|
method: method,
|
|
@@ -88,24 +88,24 @@ module BrainzLab
|
|
|
88
88
|
}
|
|
89
89
|
)
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
tags = { method: method, resource: resource }
|
|
93
|
-
BrainzLab::Flux.distribution("stripe.duration_ms", duration_ms, tags: tags) if duration_ms
|
|
94
|
-
BrainzLab::Flux.increment("stripe.requests", tags: tags)
|
|
91
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
95
92
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
tags = { method: method, resource: resource }
|
|
94
|
+
BrainzLab::Flux.distribution('stripe.duration_ms', duration_ms, tags: tags) if duration_ms
|
|
95
|
+
BrainzLab::Flux.increment('stripe.requests', tags: tags)
|
|
96
|
+
|
|
97
|
+
return unless event[:error]
|
|
98
|
+
|
|
99
|
+
BrainzLab::Flux.increment('stripe.errors', tags: tags.merge(error_type: event[:error_type]))
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
def self.track_success(method, resource, path, started_at,
|
|
103
|
+
def self.track_success(method, resource, path, started_at, _response)
|
|
104
104
|
duration_ms = ((Time.now - started_at) * 1000).round(2)
|
|
105
105
|
|
|
106
106
|
BrainzLab::Reflex.add_breadcrumb(
|
|
107
107
|
"Stripe #{method.to_s.upcase} #{resource}",
|
|
108
|
-
category:
|
|
108
|
+
category: 'payment',
|
|
109
109
|
level: :info,
|
|
110
110
|
data: {
|
|
111
111
|
method: method.to_s.upcase,
|
|
@@ -115,28 +115,28 @@ module BrainzLab
|
|
|
115
115
|
}
|
|
116
116
|
)
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
119
|
+
|
|
120
|
+
tags = { method: method.to_s.upcase, resource: resource }
|
|
121
|
+
BrainzLab::Flux.distribution('stripe.duration_ms', duration_ms, tags: tags)
|
|
122
|
+
BrainzLab::Flux.increment('stripe.requests', tags: tags)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
def self.track_error(method, resource,
|
|
126
|
-
|
|
125
|
+
def self.track_error(method, resource, _path, started_at, error)
|
|
126
|
+
((Time.now - started_at) * 1000).round(2)
|
|
127
127
|
error_type = case error
|
|
128
|
-
when Stripe::CardError then
|
|
129
|
-
when Stripe::RateLimitError then
|
|
130
|
-
when Stripe::InvalidRequestError then
|
|
131
|
-
when Stripe::AuthenticationError then
|
|
132
|
-
when Stripe::APIConnectionError then
|
|
133
|
-
when Stripe::StripeError then
|
|
134
|
-
else
|
|
128
|
+
when Stripe::CardError then 'card_error'
|
|
129
|
+
when Stripe::RateLimitError then 'rate_limit'
|
|
130
|
+
when Stripe::InvalidRequestError then 'invalid_request'
|
|
131
|
+
when Stripe::AuthenticationError then 'authentication'
|
|
132
|
+
when Stripe::APIConnectionError then 'connection'
|
|
133
|
+
when Stripe::StripeError then 'stripe_error'
|
|
134
|
+
else 'unknown'
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
BrainzLab::Reflex.add_breadcrumb(
|
|
138
138
|
"Stripe #{method.to_s.upcase} #{resource} failed: #{error.message}",
|
|
139
|
-
category:
|
|
139
|
+
category: 'payment',
|
|
140
140
|
level: :error,
|
|
141
141
|
data: {
|
|
142
142
|
method: method.to_s.upcase,
|
|
@@ -148,16 +148,15 @@ module BrainzLab
|
|
|
148
148
|
|
|
149
149
|
if BrainzLab.configuration.flux_effectively_enabled?
|
|
150
150
|
tags = { method: method.to_s.upcase, resource: resource, error_type: error_type }
|
|
151
|
-
BrainzLab::Flux.increment(
|
|
151
|
+
BrainzLab::Flux.increment('stripe.errors', tags: tags)
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
# Capture with Reflex (but filter sensitive data)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
end
|
|
155
|
+
return unless BrainzLab.configuration.reflex_effectively_enabled?
|
|
156
|
+
|
|
157
|
+
BrainzLab::Reflex.capture(error,
|
|
158
|
+
tags: { source: 'stripe', resource: resource },
|
|
159
|
+
extra: { error_type: error_type })
|
|
161
160
|
end
|
|
162
161
|
end
|
|
163
162
|
end
|
|
@@ -9,7 +9,7 @@ module BrainzLab
|
|
|
9
9
|
|
|
10
10
|
install_callbacks!
|
|
11
11
|
|
|
12
|
-
BrainzLab.debug_log(
|
|
12
|
+
BrainzLab.debug_log('[Instrumentation] Typhoeus instrumentation installed')
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
private
|
|
@@ -24,21 +24,25 @@ module BrainzLab
|
|
|
24
24
|
request = response.request
|
|
25
25
|
return unless request
|
|
26
26
|
|
|
27
|
-
uri =
|
|
27
|
+
uri = begin
|
|
28
|
+
URI.parse(request.base_url)
|
|
29
|
+
rescue StandardError
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
28
32
|
return unless uri
|
|
29
33
|
|
|
30
34
|
host = uri.host
|
|
31
35
|
return if skip_host?(host)
|
|
32
36
|
|
|
33
37
|
method = (request.options[:method] || :get).to_s.upcase
|
|
34
|
-
path = uri.path.empty? ?
|
|
38
|
+
path = uri.path.empty? ? '/' : uri.path
|
|
35
39
|
status = response.response_code
|
|
36
40
|
duration_ms = (response.total_time * 1000).round(2)
|
|
37
41
|
|
|
38
42
|
# Add breadcrumb
|
|
39
43
|
BrainzLab::Reflex.add_breadcrumb(
|
|
40
44
|
"HTTP #{method} #{host}#{path} -> #{status}",
|
|
41
|
-
category:
|
|
45
|
+
category: 'http',
|
|
42
46
|
level: response.success? ? :info : :error,
|
|
43
47
|
data: {
|
|
44
48
|
method: method,
|
|
@@ -50,19 +54,17 @@ module BrainzLab
|
|
|
50
54
|
)
|
|
51
55
|
|
|
52
56
|
# Track with Flux
|
|
53
|
-
|
|
54
|
-
tags = { host: host, method: method, status: status.to_s }
|
|
55
|
-
BrainzLab::Flux.distribution("http.typhoeus.duration_ms", duration_ms, tags: tags)
|
|
56
|
-
BrainzLab::Flux.increment("http.typhoeus.requests", tags: tags)
|
|
57
|
+
return unless BrainzLab.configuration.flux_effectively_enabled?
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
tags = { host: host, method: method, status: status.to_s }
|
|
60
|
+
BrainzLab::Flux.distribution('http.typhoeus.duration_ms', duration_ms, tags: tags)
|
|
61
|
+
BrainzLab::Flux.increment('http.typhoeus.requests', tags: tags)
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
BrainzLab::Flux.increment('http.typhoeus.errors', tags: tags) unless response.success?
|
|
64
|
+
|
|
65
|
+
return unless response.timed_out?
|
|
66
|
+
|
|
67
|
+
BrainzLab::Flux.increment('http.typhoeus.timeouts', tags: { host: host })
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def skip_host?(host)
|
|
@@ -90,8 +92,8 @@ module BrainzLab
|
|
|
90
92
|
duration_ms = ((Time.now - started_at) * 1000).round(2)
|
|
91
93
|
|
|
92
94
|
if BrainzLab.configuration.flux_effectively_enabled?
|
|
93
|
-
BrainzLab::Flux.distribution(
|
|
94
|
-
BrainzLab::Flux.distribution(
|
|
95
|
+
BrainzLab::Flux.distribution('http.typhoeus.hydra.duration_ms', duration_ms)
|
|
96
|
+
BrainzLab::Flux.distribution('http.typhoeus.hydra.request_count', request_count)
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
result
|