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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +6 -21
  3. data/README.md +16 -2
  4. data/lib/brainzlab/beacon/client.rb +38 -40
  5. data/lib/brainzlab/beacon/provisioner.rb +1 -1
  6. data/lib/brainzlab/beacon.rb +15 -15
  7. data/lib/brainzlab/configuration.rb +92 -90
  8. data/lib/brainzlab/context.rb +2 -3
  9. data/lib/brainzlab/cortex/client.rb +29 -31
  10. data/lib/brainzlab/cortex/provisioner.rb +1 -1
  11. data/lib/brainzlab/cortex.rb +7 -11
  12. data/lib/brainzlab/dendrite/client.rb +42 -44
  13. data/lib/brainzlab/dendrite/provisioner.rb +1 -1
  14. data/lib/brainzlab/dendrite.rb +4 -4
  15. data/lib/brainzlab/devtools/data/collector.rb +22 -22
  16. data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
  17. data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
  18. data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
  19. data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
  20. data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
  21. data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
  22. data/lib/brainzlab/devtools.rb +11 -11
  23. data/lib/brainzlab/flux/buffer.rb +3 -3
  24. data/lib/brainzlab/flux/client.rb +14 -16
  25. data/lib/brainzlab/flux/provisioner.rb +13 -13
  26. data/lib/brainzlab/flux.rb +8 -8
  27. data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
  28. data/lib/brainzlab/instrumentation/active_record.rb +13 -15
  29. data/lib/brainzlab/instrumentation/aws.rb +43 -39
  30. data/lib/brainzlab/instrumentation/dalli.rb +20 -20
  31. data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
  32. data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
  33. data/lib/brainzlab/instrumentation/excon.rb +27 -27
  34. data/lib/brainzlab/instrumentation/faraday.rb +3 -4
  35. data/lib/brainzlab/instrumentation/good_job.rb +28 -28
  36. data/lib/brainzlab/instrumentation/grape.rb +24 -24
  37. data/lib/brainzlab/instrumentation/graphql.rb +24 -23
  38. data/lib/brainzlab/instrumentation/httparty.rb +13 -14
  39. data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
  40. data/lib/brainzlab/instrumentation/net_http.rb +6 -6
  41. data/lib/brainzlab/instrumentation/redis.rb +14 -21
  42. data/lib/brainzlab/instrumentation/resque.rb +23 -24
  43. data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
  44. data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
  45. data/lib/brainzlab/instrumentation/stripe.rb +36 -37
  46. data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
  47. data/lib/brainzlab/instrumentation.rb +20 -20
  48. data/lib/brainzlab/nerve/client.rb +38 -40
  49. data/lib/brainzlab/nerve/provisioner.rb +1 -1
  50. data/lib/brainzlab/nerve.rb +6 -6
  51. data/lib/brainzlab/pulse/client.rb +15 -11
  52. data/lib/brainzlab/pulse/instrumentation.rb +61 -57
  53. data/lib/brainzlab/pulse/propagation.rb +28 -28
  54. data/lib/brainzlab/pulse/provisioner.rb +12 -12
  55. data/lib/brainzlab/pulse/tracer.rb +3 -3
  56. data/lib/brainzlab/pulse.rb +13 -13
  57. data/lib/brainzlab/rails/log_formatter.rb +127 -121
  58. data/lib/brainzlab/rails/log_subscriber.rb +70 -76
  59. data/lib/brainzlab/rails/railtie.rb +66 -89
  60. data/lib/brainzlab/recall/buffer.rb +1 -1
  61. data/lib/brainzlab/recall/client.rb +14 -10
  62. data/lib/brainzlab/recall/logger.rb +16 -18
  63. data/lib/brainzlab/recall/provisioner.rb +16 -16
  64. data/lib/brainzlab/recall.rb +11 -13
  65. data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
  66. data/lib/brainzlab/reflex/client.rb +14 -10
  67. data/lib/brainzlab/reflex/provisioner.rb +12 -12
  68. data/lib/brainzlab/reflex.rb +29 -29
  69. data/lib/brainzlab/sentinel/client.rb +40 -42
  70. data/lib/brainzlab/sentinel/provisioner.rb +1 -1
  71. data/lib/brainzlab/sentinel.rb +5 -5
  72. data/lib/brainzlab/signal/client.rb +12 -14
  73. data/lib/brainzlab/signal/provisioner.rb +12 -12
  74. data/lib/brainzlab/signal.rb +7 -7
  75. data/lib/brainzlab/synapse/client.rb +42 -44
  76. data/lib/brainzlab/synapse/provisioner.rb +1 -1
  77. data/lib/brainzlab/synapse.rb +6 -6
  78. data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
  79. data/lib/brainzlab/utilities/health_check.rb +53 -55
  80. data/lib/brainzlab/utilities/log_formatter.rb +38 -40
  81. data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
  82. data/lib/brainzlab/utilities.rb +4 -4
  83. data/lib/brainzlab/vault/cache.rb +1 -1
  84. data/lib/brainzlab/vault/client.rb +39 -41
  85. data/lib/brainzlab/vault/provisioner.rb +1 -1
  86. data/lib/brainzlab/vault.rb +19 -25
  87. data/lib/brainzlab/version.rb +1 -1
  88. data/lib/brainzlab/vision/client.rb +20 -20
  89. data/lib/brainzlab/vision/provisioner.rb +21 -21
  90. data/lib/brainzlab/vision.rb +17 -19
  91. data/lib/brainzlab-sdk.rb +1 -1
  92. data/lib/brainzlab.rb +22 -24
  93. data/lib/generators/brainzlab/install/install_generator.rb +29 -27
  94. metadata +1 -1
@@ -22,14 +22,14 @@ module BrainzLab
22
22
  def install_active_record!
23
23
  return unless defined?(ActiveRecord)
24
24
 
25
- ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
25
+ ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
26
26
  event = ActiveSupport::Notifications::Event.new(*args)
27
27
  next if skip_query?(event.payload)
28
28
 
29
29
  sql = event.payload[:sql]
30
30
  record_span(
31
- name: event.payload[:name] || "SQL",
32
- kind: "db",
31
+ name: event.payload[:name] || 'SQL',
32
+ kind: 'db',
33
33
  started_at: event.time,
34
34
  ended_at: event.end,
35
35
  duration_ms: event.duration,
@@ -48,12 +48,12 @@ module BrainzLab
48
48
  def install_action_view!
49
49
  return unless defined?(ActionView)
50
50
 
51
- ActiveSupport::Notifications.subscribe("render_template.action_view") do |*args|
51
+ ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args|
52
52
  event = ActiveSupport::Notifications::Event.new(*args)
53
53
 
54
54
  record_span(
55
55
  name: short_path(event.payload[:identifier]),
56
- kind: "render",
56
+ kind: 'render',
57
57
  started_at: event.time,
58
58
  ended_at: event.end,
59
59
  duration_ms: event.duration,
@@ -64,12 +64,12 @@ module BrainzLab
64
64
  )
65
65
  end
66
66
 
67
- ActiveSupport::Notifications.subscribe("render_partial.action_view") do |*args|
67
+ ActiveSupport::Notifications.subscribe('render_partial.action_view') do |*args|
68
68
  event = ActiveSupport::Notifications::Event.new(*args)
69
69
 
70
70
  record_span(
71
71
  name: short_path(event.payload[:identifier]),
72
- kind: "render",
72
+ kind: 'render',
73
73
  started_at: event.time,
74
74
  ended_at: event.end,
75
75
  duration_ms: event.duration,
@@ -80,12 +80,12 @@ module BrainzLab
80
80
  )
81
81
  end
82
82
 
83
- ActiveSupport::Notifications.subscribe("render_collection.action_view") do |*args|
83
+ ActiveSupport::Notifications.subscribe('render_collection.action_view') do |*args|
84
84
  event = ActiveSupport::Notifications::Event.new(*args)
85
85
 
86
86
  record_span(
87
87
  name: short_path(event.payload[:identifier]),
88
- kind: "render",
88
+ kind: 'render',
89
89
  started_at: event.time,
90
90
  ended_at: event.end,
91
91
  duration_ms: event.duration,
@@ -103,11 +103,11 @@ module BrainzLab
103
103
  %w[cache_read.active_support cache_write.active_support cache_delete.active_support].each do |event_name|
104
104
  ActiveSupport::Notifications.subscribe(event_name) do |*args|
105
105
  event = ActiveSupport::Notifications::Event.new(*args)
106
- operation = event_name.split(".").first.sub("cache_", "")
106
+ operation = event_name.split('.').first.sub('cache_', '')
107
107
 
108
108
  record_span(
109
109
  name: "Cache #{operation}",
110
- kind: "cache",
110
+ kind: 'cache',
111
111
  started_at: event.time,
112
112
  ended_at: event.end,
113
113
  duration_ms: event.duration,
@@ -125,7 +125,7 @@ module BrainzLab
125
125
  def install_action_controller!
126
126
  return unless defined?(ActionController)
127
127
 
128
- ActiveSupport::Notifications.subscribe("process_action.action_controller") do |*args|
128
+ ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args|
129
129
  event = ActiveSupport::Notifications::Event.new(*args)
130
130
  payload = event.payload
131
131
 
@@ -141,12 +141,12 @@ module BrainzLab
141
141
  def install_http_clients!
142
142
  # Net::HTTP instrumentation
143
143
  if defined?(Net::HTTP)
144
- ActiveSupport::Notifications.subscribe("request.net_http") do |*args|
144
+ ActiveSupport::Notifications.subscribe('request.net_http') do |*args|
145
145
  event = ActiveSupport::Notifications::Event.new(*args)
146
146
 
147
147
  record_span(
148
148
  name: "HTTP #{event.payload[:method]} #{event.payload[:host]}",
149
- kind: "http",
149
+ kind: 'http',
150
150
  started_at: event.time,
151
151
  ended_at: event.end,
152
152
  duration_ms: event.duration,
@@ -161,26 +161,26 @@ module BrainzLab
161
161
  end
162
162
 
163
163
  # Faraday instrumentation
164
- if defined?(Faraday)
165
- ActiveSupport::Notifications.subscribe("request.faraday") do |*args|
166
- event = ActiveSupport::Notifications::Event.new(*args)
167
- env = event.payload[:env]
168
- next unless env
164
+ return unless defined?(Faraday)
169
165
 
170
- record_span(
171
- name: "HTTP #{env.method.to_s.upcase} #{env.url.host}",
172
- kind: "http",
173
- started_at: event.time,
174
- ended_at: event.end,
175
- duration_ms: event.duration,
176
- data: {
177
- method: env.method.to_s.upcase,
178
- host: env.url.host,
179
- path: env.url.path,
180
- status: env.status
181
- }
182
- )
183
- end
166
+ ActiveSupport::Notifications.subscribe('request.faraday') do |*args|
167
+ event = ActiveSupport::Notifications::Event.new(*args)
168
+ env = event.payload[:env]
169
+ next unless env
170
+
171
+ record_span(
172
+ name: "HTTP #{env.method.to_s.upcase} #{env.url.host}",
173
+ kind: 'http',
174
+ started_at: event.time,
175
+ ended_at: event.end,
176
+ duration_ms: event.duration,
177
+ data: {
178
+ method: env.method.to_s.upcase,
179
+ host: env.url.host,
180
+ path: env.url.path,
181
+ status: env.status
182
+ }
183
+ )
184
184
  end
185
185
  end
186
186
 
@@ -189,13 +189,13 @@ module BrainzLab
189
189
  return unless defined?(ActiveJob)
190
190
 
191
191
  # Track job enqueuing
192
- ActiveSupport::Notifications.subscribe("enqueue.active_job") do |*args|
192
+ ActiveSupport::Notifications.subscribe('enqueue.active_job') do |*args|
193
193
  event = ActiveSupport::Notifications::Event.new(*args)
194
194
  job = event.payload[:job]
195
195
 
196
196
  record_span(
197
197
  name: "Enqueue #{job.class.name}",
198
- kind: "job",
198
+ kind: 'job',
199
199
  started_at: event.time,
200
200
  ended_at: event.end,
201
201
  duration_ms: event.duration,
@@ -208,14 +208,14 @@ module BrainzLab
208
208
  end
209
209
 
210
210
  # Track job retry
211
- ActiveSupport::Notifications.subscribe("retry_stopped.active_job") do |*args|
211
+ ActiveSupport::Notifications.subscribe('retry_stopped.active_job') do |*args|
212
212
  event = ActiveSupport::Notifications::Event.new(*args)
213
213
  job = event.payload[:job]
214
214
  error = event.payload[:error]
215
215
 
216
216
  record_span(
217
217
  name: "Retry stopped #{job.class.name}",
218
- kind: "job",
218
+ kind: 'job',
219
219
  started_at: event.time,
220
220
  ended_at: event.end,
221
221
  duration_ms: event.duration,
@@ -232,14 +232,14 @@ module BrainzLab
232
232
  end
233
233
 
234
234
  # Track job discard
235
- ActiveSupport::Notifications.subscribe("discard.active_job") do |*args|
235
+ ActiveSupport::Notifications.subscribe('discard.active_job') do |*args|
236
236
  event = ActiveSupport::Notifications::Event.new(*args)
237
237
  job = event.payload[:job]
238
238
  error = event.payload[:error]
239
239
 
240
240
  record_span(
241
241
  name: "Discarded #{job.class.name}",
242
- kind: "job",
242
+ kind: 'job',
243
243
  started_at: event.time,
244
244
  ended_at: event.end,
245
245
  duration_ms: event.duration,
@@ -260,12 +260,12 @@ module BrainzLab
260
260
  def install_action_cable!
261
261
  return unless defined?(ActionCable)
262
262
 
263
- ActiveSupport::Notifications.subscribe("perform_action.action_cable") do |*args|
263
+ ActiveSupport::Notifications.subscribe('perform_action.action_cable') do |*args|
264
264
  event = ActiveSupport::Notifications::Event.new(*args)
265
265
 
266
266
  record_span(
267
267
  name: "Cable #{event.payload[:channel_class]}##{event.payload[:action]}",
268
- kind: "cable",
268
+ kind: 'cable',
269
269
  started_at: event.time,
270
270
  ended_at: event.end,
271
271
  duration_ms: event.duration,
@@ -276,12 +276,12 @@ module BrainzLab
276
276
  )
277
277
  end
278
278
 
279
- ActiveSupport::Notifications.subscribe("transmit.action_cable") do |*args|
279
+ ActiveSupport::Notifications.subscribe('transmit.action_cable') do |*args|
280
280
  event = ActiveSupport::Notifications::Event.new(*args)
281
281
 
282
282
  record_span(
283
283
  name: "Cable transmit #{event.payload[:channel_class]}",
284
- kind: "cable",
284
+ kind: 'cable',
285
285
  started_at: event.time,
286
286
  ended_at: event.end,
287
287
  duration_ms: event.duration,
@@ -292,12 +292,12 @@ module BrainzLab
292
292
  )
293
293
  end
294
294
 
295
- ActiveSupport::Notifications.subscribe("broadcast.action_cable") do |*args|
295
+ ActiveSupport::Notifications.subscribe('broadcast.action_cable') do |*args|
296
296
  event = ActiveSupport::Notifications::Event.new(*args)
297
297
 
298
298
  record_span(
299
299
  name: "Cable broadcast #{event.payload[:broadcasting]}",
300
- kind: "cable",
300
+ kind: 'cable',
301
301
  started_at: event.time,
302
302
  ended_at: event.end,
303
303
  duration_ms: event.duration,
@@ -309,7 +309,8 @@ module BrainzLab
309
309
  end
310
310
  end
311
311
 
312
- def record_span(name:, kind:, started_at:, ended_at:, duration_ms:, error: false, error_class: nil, error_message: nil, data: {})
312
+ def record_span(name:, kind:, started_at:, ended_at:, duration_ms:, error: false, error_class: nil,
313
+ error_message: nil, data: {})
313
314
  spans = Thread.current[:brainzlab_pulse_spans]
314
315
  return unless spans
315
316
 
@@ -334,10 +335,10 @@ module BrainzLab
334
335
 
335
336
  def skip_query?(payload)
336
337
  # Skip SCHEMA queries and internal Rails queries
337
- return true if payload[:name] == "SCHEMA"
338
- return true if payload[:name]&.start_with?("EXPLAIN")
339
- return true if payload[:sql]&.include?("pg_")
340
- return true if payload[:sql]&.include?("information_schema")
338
+ return true if payload[:name] == 'SCHEMA'
339
+ return true if payload[:name]&.start_with?('EXPLAIN')
340
+ return true if payload[:sql]&.include?('pg_')
341
+ return true if payload[:sql]&.include?('information_schema')
341
342
  return true if payload[:cached] && !include_cached_queries?
342
343
 
343
344
  false
@@ -349,17 +350,20 @@ module BrainzLab
349
350
 
350
351
  def truncate_sql(sql)
351
352
  return nil unless sql
353
+
352
354
  sql.to_s[0, 1000]
353
355
  end
354
356
 
355
357
  def truncate_key(key)
356
358
  return nil unless key
359
+
357
360
  key.to_s[0, 200]
358
361
  end
359
362
 
360
363
  def short_path(path)
361
364
  return nil unless path
362
- path.to_s.split("/").last(2).join("/")
365
+
366
+ path.to_s.split('/').last(2).join('/')
363
367
  end
364
368
 
365
369
  def extract_table(sql)
@@ -383,12 +387,12 @@ module BrainzLab
383
387
  return nil unless sql
384
388
 
385
389
  case sql.to_s.strip.upcase
386
- when /\ASELECT/i then "SELECT"
387
- when /\AINSERT/i then "INSERT"
388
- when /\AUPDATE/i then "UPDATE"
389
- when /\ADELETE/i then "DELETE"
390
- when /\ABEGIN/i, /\ACOMMIT/i, /\AROLLBACK/i then "TRANSACTION"
391
- else "QUERY"
390
+ when /\ASELECT/i then 'SELECT'
391
+ when /\AINSERT/i then 'INSERT'
392
+ when /\AUPDATE/i then 'UPDATE'
393
+ when /\ADELETE/i then 'DELETE'
394
+ when /\ABEGIN/i, /\ACOMMIT/i, /\AROLLBACK/i then 'TRANSACTION'
395
+ else 'QUERY'
392
396
  end
393
397
  end
394
398
  end
@@ -6,18 +6,18 @@ module BrainzLab
6
6
  # https://www.w3.org/TR/trace-context/
7
7
  module Propagation
8
8
  # W3C Trace Context header names
9
- TRACEPARENT_HEADER = "traceparent"
10
- TRACESTATE_HEADER = "tracestate"
9
+ TRACEPARENT_HEADER = 'traceparent'
10
+ TRACESTATE_HEADER = 'tracestate'
11
11
 
12
12
  # HTTP header versions (with HTTP_ prefix for Rack env)
13
- HTTP_TRACEPARENT = "HTTP_TRACEPARENT"
14
- HTTP_TRACESTATE = "HTTP_TRACESTATE"
13
+ HTTP_TRACEPARENT = 'HTTP_TRACEPARENT'
14
+ HTTP_TRACESTATE = 'HTTP_TRACESTATE'
15
15
 
16
16
  # Also support B3 format for compatibility
17
- B3_TRACE_ID = "X-B3-TraceId"
18
- B3_SPAN_ID = "X-B3-SpanId"
19
- B3_SAMPLED = "X-B3-Sampled"
20
- B3_PARENT_SPAN_ID = "X-B3-ParentSpanId"
17
+ B3_TRACE_ID = 'X-B3-TraceId'
18
+ B3_SPAN_ID = 'X-B3-SpanId'
19
+ B3_SAMPLED = 'X-B3-Sampled'
20
+ B3_PARENT_SPAN_ID = 'X-B3-ParentSpanId'
21
21
 
22
22
  class Context
23
23
  attr_accessor :trace_id, :span_id, :parent_span_id, :sampled, :tracestate
@@ -137,8 +137,8 @@ module BrainzLab
137
137
  # traceparent: version-traceid-spanid-flags
138
138
  # Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
139
139
  def inject_w3c(headers, ctx)
140
- version = "00"
141
- flags = ctx.sampled ? "01" : "00"
140
+ version = '00'
141
+ flags = ctx.sampled ? '01' : '00'
142
142
  trace_id = normalize_trace_id(ctx.trace_id, 32)
143
143
  span_id = normalize_trace_id(ctx.span_id, 16)
144
144
 
@@ -152,31 +152,31 @@ module BrainzLab
152
152
  def extract_w3c(headers)
153
153
  traceparent = headers[TRACEPARENT_HEADER] ||
154
154
  headers[HTTP_TRACEPARENT] ||
155
- headers["Traceparent"]
155
+ headers['Traceparent']
156
156
  return nil unless traceparent
157
157
 
158
158
  # Parse: version-traceid-spanid-flags
159
- parts = traceparent.to_s.split("-")
159
+ parts = traceparent.to_s.split('-')
160
160
  return nil if parts.length < 4
161
161
 
162
162
  version, trace_id, span_id, flags = parts
163
163
 
164
164
  # Validate version
165
- return nil unless version == "00"
165
+ return nil unless version == '00'
166
166
 
167
167
  # Validate trace_id (32 hex chars, not all zeros)
168
168
  return nil unless trace_id&.match?(/\A[a-f0-9]{32}\z/i)
169
- return nil if trace_id == "0" * 32
169
+ return nil if trace_id == '0' * 32
170
170
 
171
171
  # Validate span_id (16 hex chars, not all zeros)
172
172
  return nil unless span_id&.match?(/\A[a-f0-9]{16}\z/i)
173
- return nil if span_id == "0" * 16
173
+ return nil if span_id == '0' * 16
174
174
 
175
175
  sampled = flags.to_i(16) & 0x01 == 1
176
176
 
177
177
  tracestate = headers[TRACESTATE_HEADER] ||
178
178
  headers[HTTP_TRACESTATE] ||
179
- headers["Tracestate"]
179
+ headers['Tracestate']
180
180
 
181
181
  Context.new(
182
182
  trace_id: trace_id,
@@ -192,7 +192,7 @@ module BrainzLab
192
192
  def inject_b3(headers, ctx)
193
193
  headers[B3_TRACE_ID] = normalize_trace_id(ctx.trace_id, 32)
194
194
  headers[B3_SPAN_ID] = normalize_trace_id(ctx.span_id, 16)
195
- headers[B3_SAMPLED] = ctx.sampled ? "1" : "0"
195
+ headers[B3_SAMPLED] = ctx.sampled ? '1' : '0'
196
196
  headers[B3_PARENT_SPAN_ID] = ctx.parent_span_id if ctx.parent_span_id
197
197
 
198
198
  headers
@@ -201,23 +201,23 @@ module BrainzLab
201
201
  # B3 format extraction
202
202
  def extract_b3(headers)
203
203
  trace_id = headers[B3_TRACE_ID] ||
204
- headers["HTTP_X_B3_TRACEID"] ||
205
- headers["x-b3-traceid"]
204
+ headers['HTTP_X_B3_TRACEID'] ||
205
+ headers['x-b3-traceid']
206
206
  return nil unless trace_id
207
207
 
208
208
  span_id = headers[B3_SPAN_ID] ||
209
- headers["HTTP_X_B3_SPANID"] ||
210
- headers["x-b3-spanid"]
209
+ headers['HTTP_X_B3_SPANID'] ||
210
+ headers['x-b3-spanid']
211
211
  return nil unless span_id
212
212
 
213
213
  sampled_header = headers[B3_SAMPLED] ||
214
- headers["HTTP_X_B3_SAMPLED"] ||
215
- headers["x-b3-sampled"]
216
- sampled = sampled_header != "0"
214
+ headers['HTTP_X_B3_SAMPLED'] ||
215
+ headers['x-b3-sampled']
216
+ sampled = sampled_header != '0'
217
217
 
218
218
  parent_span_id = headers[B3_PARENT_SPAN_ID] ||
219
- headers["HTTP_X_B3_PARENTSPANID"] ||
220
- headers["x-b3-parentspanid"]
219
+ headers['HTTP_X_B3_PARENTSPANID'] ||
220
+ headers['x-b3-parentspanid']
221
221
 
222
222
  Context.new(
223
223
  trace_id: trace_id,
@@ -232,8 +232,8 @@ module BrainzLab
232
232
  def normalize_trace_id(id, length)
233
233
  return nil unless id
234
234
 
235
- hex = id.to_s.gsub("-", "").downcase
236
- hex.rjust(length, "0").slice(0, length)
235
+ hex = id.to_s.gsub('-', '').downcase
236
+ hex.rjust(length, '0').slice(0, length)
237
237
  end
238
238
  end
239
239
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "uri"
5
- require "json"
6
- require "fileutils"
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'fileutils'
7
7
 
8
8
  module BrainzLab
9
9
  module Pulse
10
10
  class Provisioner
11
- CACHE_DIR = ENV.fetch("BRAINZLAB_CACHE_DIR") { File.join(Dir.home, ".brainzlab") }
11
+ CACHE_DIR = ENV.fetch('BRAINZLAB_CACHE_DIR') { File.join(Dir.home, '.brainzlab') }
12
12
 
13
13
  def initialize(config)
14
14
  @config = config
@@ -38,10 +38,10 @@ module BrainzLab
38
38
 
39
39
  def should_provision?
40
40
  return false unless @config.pulse_auto_provision
41
- return false unless @config.app_name.to_s.strip.length > 0
41
+ return false unless @config.app_name.to_s.strip.length.positive?
42
42
  # Only skip if pulse_api_key is already set
43
- return false if @config.pulse_api_key.to_s.strip.length > 0
44
- return false unless @config.pulse_master_key.to_s.strip.length > 0
43
+ return false if @config.pulse_api_key.to_s.strip.length.positive?
44
+ return false unless @config.pulse_master_key.to_s.strip.length.positive?
45
45
 
46
46
  true
47
47
  end
@@ -49,9 +49,9 @@ module BrainzLab
49
49
  def provision_project
50
50
  uri = URI.parse("#{@config.pulse_url}/api/v1/projects/provision")
51
51
  request = Net::HTTP::Post.new(uri)
52
- request["Content-Type"] = "application/json"
53
- request["X-Master-Key"] = @config.pulse_master_key
54
- request["User-Agent"] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
52
+ request['Content-Type'] = 'application/json'
53
+ request['X-Master-Key'] = @config.pulse_master_key
54
+ request['User-Agent'] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
55
55
  request.body = JSON.generate({ name: @config.app_name })
56
56
 
57
57
  response = execute(uri, request)
@@ -98,7 +98,7 @@ module BrainzLab
98
98
 
99
99
  def execute(uri, request)
100
100
  http = Net::HTTP.new(uri.host, uri.port)
101
- http.use_ssl = uri.scheme == "https"
101
+ http.use_ssl = uri.scheme == 'https'
102
102
  http.open_timeout = 5
103
103
  http.read_timeout = 10
104
104
  http.request(request)
@@ -16,7 +16,7 @@ module BrainzLab
16
16
  Thread.current[:brainzlab_pulse_spans] ||= []
17
17
  end
18
18
 
19
- def start_trace(name, kind: "custom", **attributes)
19
+ def start_trace(name, kind: 'custom', **attributes)
20
20
  trace = {
21
21
  trace_id: SecureRandom.uuid,
22
22
  name: name,
@@ -64,7 +64,7 @@ module BrainzLab
64
64
  payload
65
65
  end
66
66
 
67
- def span(name, kind: "custom", **data)
67
+ def span(name, kind: 'custom', **data)
68
68
  span_data = {
69
69
  span_id: SecureRandom.uuid,
70
70
  name: name,
@@ -91,7 +91,7 @@ module BrainzLab
91
91
 
92
92
  private
93
93
 
94
- def format_span(span, trace_started_at)
94
+ def format_span(span, _trace_started_at)
95
95
  {
96
96
  span_id: span[:span_id],
97
97
  parent_span_id: span[:parent_span_id],
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "pulse/client"
4
- require_relative "pulse/provisioner"
5
- require_relative "pulse/tracer"
6
- require_relative "pulse/instrumentation"
7
- require_relative "pulse/propagation"
3
+ require_relative 'pulse/client'
4
+ require_relative 'pulse/provisioner'
5
+ require_relative 'pulse/tracer'
6
+ require_relative 'pulse/instrumentation'
7
+ require_relative 'pulse/propagation'
8
8
 
9
9
  module BrainzLab
10
10
  module Pulse
@@ -13,7 +13,7 @@ module BrainzLab
13
13
  # @param name [String] the trace name
14
14
  # @param kind [String] trace kind (request, job, custom)
15
15
  # @param parent_context [Propagation::Context] optional parent context for distributed tracing
16
- def start_trace(name, kind: "custom", parent_context: nil, **attributes)
16
+ def start_trace(name, kind: 'custom', parent_context: nil, **attributes)
17
17
  return nil unless enabled?
18
18
 
19
19
  ensure_provisioned!
@@ -36,15 +36,15 @@ module BrainzLab
36
36
  end
37
37
 
38
38
  # Add a span to the current trace
39
- def span(name, kind: "custom", **data)
39
+ def span(name, kind: 'custom', **data, &)
40
40
  return yield unless enabled?
41
41
  return yield unless tracer.current_trace
42
42
 
43
- tracer.span(name, kind: kind, **data) { yield }
43
+ tracer.span(name, kind: kind, **data, &)
44
44
  end
45
45
 
46
46
  # Record a complete trace (for when you have all data upfront)
47
- def record_trace(name, kind: "request", started_at:, ended_at:, **attributes)
47
+ def record_trace(name, started_at:, ended_at:, kind: 'request', **attributes)
48
48
  return unless enabled?
49
49
 
50
50
  ensure_provisioned!
@@ -55,7 +55,7 @@ module BrainzLab
55
55
  end
56
56
 
57
57
  # Record a custom metric
58
- def record_metric(name, value:, kind: "gauge", tags: {})
58
+ def record_metric(name, value:, kind: 'gauge', tags: {})
59
59
  return unless enabled?
60
60
 
61
61
  ensure_provisioned!
@@ -74,15 +74,15 @@ module BrainzLab
74
74
 
75
75
  # Convenience methods for metrics
76
76
  def gauge(name, value, tags: {})
77
- record_metric(name, value: value, kind: "gauge", tags: tags)
77
+ record_metric(name, value: value, kind: 'gauge', tags: tags)
78
78
  end
79
79
 
80
80
  def counter(name, value = 1, tags: {})
81
- record_metric(name, value: value, kind: "counter", tags: tags)
81
+ record_metric(name, value: value, kind: 'counter', tags: tags)
82
82
  end
83
83
 
84
84
  def histogram(name, value, tags: {})
85
- record_metric(name, value: value, kind: "histogram", tags: tags)
85
+ record_metric(name, value: value, kind: 'histogram', tags: tags)
86
86
  end
87
87
 
88
88
  def ensure_provisioned!