brainzlab 0.1.2 → 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.
Files changed (104) 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 +112 -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_cable.rb +351 -0
  28. data/lib/brainzlab/instrumentation/action_controller.rb +649 -0
  29. data/lib/brainzlab/instrumentation/action_dispatch.rb +259 -0
  30. data/lib/brainzlab/instrumentation/action_mailbox.rb +197 -0
  31. data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
  32. data/lib/brainzlab/instrumentation/action_view.rb +380 -0
  33. data/lib/brainzlab/instrumentation/active_job.rb +569 -0
  34. data/lib/brainzlab/instrumentation/active_record.rb +467 -36
  35. data/lib/brainzlab/instrumentation/active_storage.rb +541 -0
  36. data/lib/brainzlab/instrumentation/active_support_cache.rb +700 -0
  37. data/lib/brainzlab/instrumentation/aws.rb +43 -39
  38. data/lib/brainzlab/instrumentation/dalli.rb +20 -20
  39. data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
  40. data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
  41. data/lib/brainzlab/instrumentation/excon.rb +27 -27
  42. data/lib/brainzlab/instrumentation/faraday.rb +3 -4
  43. data/lib/brainzlab/instrumentation/good_job.rb +28 -28
  44. data/lib/brainzlab/instrumentation/grape.rb +24 -24
  45. data/lib/brainzlab/instrumentation/graphql.rb +24 -23
  46. data/lib/brainzlab/instrumentation/httparty.rb +13 -14
  47. data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
  48. data/lib/brainzlab/instrumentation/net_http.rb +6 -6
  49. data/lib/brainzlab/instrumentation/rails_deprecation.rb +139 -0
  50. data/lib/brainzlab/instrumentation/railties.rb +134 -0
  51. data/lib/brainzlab/instrumentation/redis.rb +14 -21
  52. data/lib/brainzlab/instrumentation/resque.rb +23 -24
  53. data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
  54. data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
  55. data/lib/brainzlab/instrumentation/stripe.rb +36 -37
  56. data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
  57. data/lib/brainzlab/instrumentation.rb +111 -21
  58. data/lib/brainzlab/nerve/client.rb +38 -40
  59. data/lib/brainzlab/nerve/provisioner.rb +1 -1
  60. data/lib/brainzlab/nerve.rb +6 -6
  61. data/lib/brainzlab/pulse/client.rb +15 -11
  62. data/lib/brainzlab/pulse/instrumentation.rb +61 -57
  63. data/lib/brainzlab/pulse/propagation.rb +28 -28
  64. data/lib/brainzlab/pulse/provisioner.rb +12 -12
  65. data/lib/brainzlab/pulse/tracer.rb +3 -3
  66. data/lib/brainzlab/pulse.rb +13 -13
  67. data/lib/brainzlab/rails/log_formatter.rb +127 -121
  68. data/lib/brainzlab/rails/log_subscriber.rb +70 -76
  69. data/lib/brainzlab/rails/railtie.rb +66 -89
  70. data/lib/brainzlab/recall/buffer.rb +1 -1
  71. data/lib/brainzlab/recall/client.rb +14 -10
  72. data/lib/brainzlab/recall/logger.rb +16 -18
  73. data/lib/brainzlab/recall/provisioner.rb +16 -16
  74. data/lib/brainzlab/recall.rb +11 -13
  75. data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
  76. data/lib/brainzlab/reflex/client.rb +14 -10
  77. data/lib/brainzlab/reflex/provisioner.rb +12 -12
  78. data/lib/brainzlab/reflex.rb +29 -29
  79. data/lib/brainzlab/sentinel/client.rb +40 -42
  80. data/lib/brainzlab/sentinel/provisioner.rb +1 -1
  81. data/lib/brainzlab/sentinel.rb +5 -5
  82. data/lib/brainzlab/signal/client.rb +12 -14
  83. data/lib/brainzlab/signal/provisioner.rb +12 -12
  84. data/lib/brainzlab/signal.rb +7 -7
  85. data/lib/brainzlab/synapse/client.rb +42 -44
  86. data/lib/brainzlab/synapse/provisioner.rb +1 -1
  87. data/lib/brainzlab/synapse.rb +6 -6
  88. data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
  89. data/lib/brainzlab/utilities/health_check.rb +53 -55
  90. data/lib/brainzlab/utilities/log_formatter.rb +38 -40
  91. data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
  92. data/lib/brainzlab/utilities.rb +4 -4
  93. data/lib/brainzlab/vault/cache.rb +1 -1
  94. data/lib/brainzlab/vault/client.rb +39 -41
  95. data/lib/brainzlab/vault/provisioner.rb +1 -1
  96. data/lib/brainzlab/vault.rb +19 -25
  97. data/lib/brainzlab/version.rb +1 -1
  98. data/lib/brainzlab/vision/client.rb +20 -20
  99. data/lib/brainzlab/vision/provisioner.rb +21 -21
  100. data/lib/brainzlab/vision.rb +17 -19
  101. data/lib/brainzlab-sdk.rb +1 -1
  102. data/lib/brainzlab.rb +22 -24
  103. data/lib/generators/brainzlab/install/install_generator.rb +29 -27
  104. metadata +11 -1
@@ -10,7 +10,7 @@ module BrainzLab
10
10
  install_notifier!
11
11
  install_middleware!
12
12
 
13
- BrainzLab.debug_log("[Instrumentation] GoodJob instrumentation installed")
13
+ BrainzLab.debug_log('[Instrumentation] GoodJob instrumentation installed')
14
14
  end
15
15
 
16
16
  private
@@ -19,12 +19,12 @@ module BrainzLab
19
19
  return unless defined?(::ActiveSupport::Notifications)
20
20
 
21
21
  # GoodJob emits ActiveSupport notifications
22
- ::ActiveSupport::Notifications.subscribe("perform_job.good_job") do |*args|
22
+ ::ActiveSupport::Notifications.subscribe('perform_job.good_job') do |*args|
23
23
  event = ::ActiveSupport::Notifications::Event.new(*args)
24
24
  handle_perform(event)
25
25
  end
26
26
 
27
- ::ActiveSupport::Notifications.subscribe("finished_job_task.good_job") do |*args|
27
+ ::ActiveSupport::Notifications.subscribe('finished_job_task.good_job') do |*args|
28
28
  event = ::ActiveSupport::Notifications::Event.new(*args)
29
29
  handle_finished(event)
30
30
  end
@@ -34,25 +34,28 @@ module BrainzLab
34
34
  return unless defined?(::GoodJob::Adapter)
35
35
 
36
36
  # Add our callback to GoodJob
37
- if ::GoodJob.respond_to?(:on_thread_error)
38
- ::GoodJob.on_thread_error = ->(error) do
39
- BrainzLab::Reflex.capture(error, tags: { source: "good_job" }) if BrainzLab.configuration.reflex_effectively_enabled?
37
+ return unless ::GoodJob.respond_to?(:on_thread_error)
38
+
39
+ ::GoodJob.on_thread_error = lambda { |error|
40
+ if BrainzLab.configuration.reflex_effectively_enabled?
41
+ BrainzLab::Reflex.capture(error,
42
+ tags: { source: 'good_job' })
40
43
  end
41
- end
44
+ }
42
45
  end
43
46
 
44
47
  def handle_perform(event)
45
48
  payload = event.payload
46
49
  job = payload[:job]
47
- job_class = job&.class&.name || payload[:job_class] || "Unknown"
48
- queue = job&.queue_name || payload[:queue_name] || "default"
50
+ job_class = job&.class&.name || payload[:job_class] || 'Unknown'
51
+ queue = job&.queue_name || payload[:queue_name] || 'default'
49
52
  duration_ms = event.duration.round(2)
50
53
 
51
54
  # Track with Pulse
52
55
  if BrainzLab.configuration.pulse_effectively_enabled?
53
56
  BrainzLab::Pulse.record_trace(
54
57
  "job.#{job_class}",
55
- kind: "job",
58
+ kind: 'job',
56
59
  started_at: event.time,
57
60
  ended_at: event.end,
58
61
  job_class: job_class,
@@ -67,33 +70,30 @@ module BrainzLab
67
70
  # Track with Flux
68
71
  if BrainzLab.configuration.flux_effectively_enabled?
69
72
  tags = { job_class: job_class, queue: queue }
70
- BrainzLab::Flux.distribution("good_job.job.duration_ms", duration_ms, tags: tags)
71
- BrainzLab::Flux.increment("good_job.job.processed", tags: tags)
73
+ BrainzLab::Flux.distribution('good_job.job.duration_ms', duration_ms, tags: tags)
74
+ BrainzLab::Flux.increment('good_job.job.processed', tags: tags)
72
75
 
73
- if payload[:error]
74
- BrainzLab::Flux.increment("good_job.job.failed", tags: tags)
75
- end
76
+ BrainzLab::Flux.increment('good_job.job.failed', tags: tags) if payload[:error]
76
77
  end
77
78
 
78
79
  # Capture error with Reflex
79
- if payload[:error] && BrainzLab.configuration.reflex_effectively_enabled?
80
- BrainzLab::Reflex.capture(payload[:error],
81
- tags: { job_class: job_class, queue: queue, source: "good_job" },
82
- extra: { job_id: job&.job_id, duration_ms: duration_ms }
83
- )
84
- end
80
+ return unless payload[:error] && BrainzLab.configuration.reflex_effectively_enabled?
81
+
82
+ BrainzLab::Reflex.capture(payload[:error],
83
+ tags: { job_class: job_class, queue: queue, source: 'good_job' },
84
+ extra: { job_id: job&.job_id, duration_ms: duration_ms })
85
85
  end
86
86
 
87
87
  def handle_finished(event)
88
88
  payload = event.payload
89
89
 
90
- if BrainzLab.configuration.flux_effectively_enabled?
91
- result = payload[:result]
92
- if result == :discarded
93
- BrainzLab::Flux.increment("good_job.job.discarded")
94
- elsif result == :retried
95
- BrainzLab::Flux.increment("good_job.job.retried")
96
- end
90
+ return unless BrainzLab.configuration.flux_effectively_enabled?
91
+
92
+ result = payload[:result]
93
+ if result == :discarded
94
+ BrainzLab::Flux.increment('good_job.job.discarded')
95
+ elsif result == :retried
96
+ BrainzLab::Flux.increment('good_job.job.retried')
97
97
  end
98
98
  end
99
99
  end
@@ -14,7 +14,7 @@ module BrainzLab
14
14
  install_notifications!
15
15
 
16
16
  @installed = true
17
- BrainzLab.debug_log("Grape instrumentation installed")
17
+ BrainzLab.debug_log('Grape instrumentation installed')
18
18
  end
19
19
 
20
20
  def installed?
@@ -29,23 +29,23 @@ module BrainzLab
29
29
 
30
30
  def install_notifications!
31
31
  # Grape emits these notifications
32
- ActiveSupport::Notifications.subscribe("endpoint_run.grape") do |*args|
32
+ ActiveSupport::Notifications.subscribe('endpoint_run.grape') do |*args|
33
33
  event = ActiveSupport::Notifications::Event.new(*args)
34
34
  record_endpoint(event)
35
35
  end
36
36
 
37
- ActiveSupport::Notifications.subscribe("endpoint_render.grape") do |*args|
37
+ ActiveSupport::Notifications.subscribe('endpoint_render.grape') do |*args|
38
38
  event = ActiveSupport::Notifications::Event.new(*args)
39
39
  record_render(event)
40
40
  end
41
41
 
42
- ActiveSupport::Notifications.subscribe("endpoint_run_filters.grape") do |*args|
42
+ ActiveSupport::Notifications.subscribe('endpoint_run_filters.grape') do |*args|
43
43
  event = ActiveSupport::Notifications::Event.new(*args)
44
44
  record_filters(event)
45
45
  end
46
46
 
47
47
  # Format validation
48
- ActiveSupport::Notifications.subscribe("format_response.grape") do |*args|
48
+ ActiveSupport::Notifications.subscribe('format_response.grape') do |*args|
49
49
  event = ActiveSupport::Notifications::Event.new(*args)
50
50
  record_format(event)
51
51
  end
@@ -58,19 +58,19 @@ module BrainzLab
58
58
  endpoint = payload[:endpoint]
59
59
  env = payload[:env] || {}
60
60
 
61
- method = env["REQUEST_METHOD"] || "GET"
62
- path = endpoint&.options&.dig(:path)&.first || env["PATH_INFO"] || "/"
61
+ method = env['REQUEST_METHOD'] || 'GET'
62
+ path = endpoint&.options&.dig(:path)&.first || env['PATH_INFO'] || '/'
63
63
  route_pattern = extract_route_pattern(endpoint)
64
64
  duration_ms = event.duration.round(2)
65
65
 
66
- status = env["api.endpoint"]&.status || 200
66
+ status = env['api.endpoint']&.status || 200
67
67
  level = status >= 400 ? :error : :info
68
68
 
69
69
  # Add breadcrumb for Reflex
70
70
  if BrainzLab.configuration.reflex_enabled
71
71
  BrainzLab::Reflex.add_breadcrumb(
72
72
  "Grape #{method} #{route_pattern}",
73
- category: "grape.endpoint",
73
+ category: 'grape.endpoint',
74
74
  level: level,
75
75
  data: {
76
76
  method: method,
@@ -85,7 +85,7 @@ module BrainzLab
85
85
  # Record span for Pulse
86
86
  record_span(
87
87
  name: "Grape #{method} #{route_pattern}",
88
- kind: "grape",
88
+ kind: 'grape',
89
89
  started_at: event.time,
90
90
  ended_at: event.end,
91
91
  duration_ms: duration_ms,
@@ -117,12 +117,12 @@ module BrainzLab
117
117
  duration_ms = event.duration.round(2)
118
118
 
119
119
  record_span(
120
- name: "Grape render",
121
- kind: "grape.render",
120
+ name: 'Grape render',
121
+ kind: 'grape.render',
122
122
  started_at: event.time,
123
123
  ended_at: event.end,
124
124
  duration_ms: duration_ms,
125
- data: { phase: "render" }
125
+ data: { phase: 'render' }
126
126
  )
127
127
  rescue StandardError => e
128
128
  BrainzLab.debug_log("Grape render recording failed: #{e.message}")
@@ -131,11 +131,11 @@ module BrainzLab
131
131
  def record_filters(event)
132
132
  payload = event.payload
133
133
  duration_ms = event.duration.round(2)
134
- filter_type = payload[:type] || "filter"
134
+ filter_type = payload[:type] || 'filter'
135
135
 
136
136
  record_span(
137
137
  name: "Grape #{filter_type} filters",
138
- kind: "grape.filter",
138
+ kind: 'grape.filter',
139
139
  started_at: event.time,
140
140
  ended_at: event.end,
141
141
  duration_ms: duration_ms,
@@ -149,12 +149,12 @@ module BrainzLab
149
149
  duration_ms = event.duration.round(2)
150
150
 
151
151
  record_span(
152
- name: "Grape format response",
153
- kind: "grape.format",
152
+ name: 'Grape format response',
153
+ kind: 'grape.format',
154
154
  started_at: event.time,
155
155
  ended_at: event.end,
156
156
  duration_ms: duration_ms,
157
- data: { phase: "format" }
157
+ data: { phase: 'format' }
158
158
  )
159
159
  rescue StandardError => e
160
160
  BrainzLab.debug_log("Grape format recording failed: #{e.message}")
@@ -177,14 +177,14 @@ module BrainzLab
177
177
  end
178
178
 
179
179
  def extract_route_pattern(endpoint)
180
- return "/" unless endpoint
180
+ return '/' unless endpoint
181
181
 
182
182
  route = endpoint.route
183
- return "/" unless route
183
+ return '/' unless route
184
184
 
185
- route.pattern&.path || route.path || "/"
185
+ route.pattern&.path || route.path || '/'
186
186
  rescue StandardError
187
- "/"
187
+ '/'
188
188
  end
189
189
  end
190
190
 
@@ -243,14 +243,14 @@ module BrainzLab
243
243
  path = request.path
244
244
 
245
245
  # Get route pattern from Grape if available
246
- route_pattern = env["grape.routing_args"]&.dig(:route_info)&.pattern&.path || path
246
+ route_pattern = env['grape.routing_args']&.dig(:route_info)&.pattern&.path || path
247
247
 
248
248
  spans = Thread.current[:brainzlab_pulse_spans] || []
249
249
 
250
250
  payload = {
251
251
  trace_id: SecureRandom.uuid,
252
252
  name: "#{method} #{route_pattern}",
253
- kind: "request",
253
+ kind: 'request',
254
254
  started_at: started_at.utc.iso8601(3),
255
255
  ended_at: ended_at.utc.iso8601(3),
256
256
  duration_ms: duration_ms,
@@ -13,14 +13,14 @@ module BrainzLab
13
13
  # For GraphQL Ruby 2.0+
14
14
  if ::GraphQL::Schema.respond_to?(:trace_with)
15
15
  # Will be installed per-schema via BrainzLab::GraphQL::Tracer
16
- BrainzLab.debug_log("GraphQL tracer available - add `trace_with BrainzLab::Instrumentation::GraphQLInstrumentation::Tracer` to your schema")
16
+ BrainzLab.debug_log('GraphQL tracer available - add `trace_with BrainzLab::Instrumentation::GraphQLInstrumentation::Tracer` to your schema')
17
17
  end
18
18
 
19
19
  # Subscribe to ActiveSupport notifications if available
20
20
  install_notifications!
21
21
 
22
22
  @installed = true
23
- BrainzLab.debug_log("GraphQL instrumentation installed")
23
+ BrainzLab.debug_log('GraphQL instrumentation installed')
24
24
  end
25
25
 
26
26
  def installed?
@@ -35,17 +35,17 @@ module BrainzLab
35
35
 
36
36
  def install_notifications!
37
37
  # GraphQL-ruby emits ActiveSupport notifications
38
- ActiveSupport::Notifications.subscribe("execute.graphql") do |*args|
38
+ ActiveSupport::Notifications.subscribe('execute.graphql') do |*args|
39
39
  event = ActiveSupport::Notifications::Event.new(*args)
40
40
  record_execution(event)
41
41
  end
42
42
 
43
- ActiveSupport::Notifications.subscribe("analyze.graphql") do |*args|
43
+ ActiveSupport::Notifications.subscribe('analyze.graphql') do |*args|
44
44
  event = ActiveSupport::Notifications::Event.new(*args)
45
45
  record_analyze(event)
46
46
  end
47
47
 
48
- ActiveSupport::Notifications.subscribe("validate.graphql") do |*args|
48
+ ActiveSupport::Notifications.subscribe('validate.graphql') do |*args|
49
49
  event = ActiveSupport::Notifications::Event.new(*args)
50
50
  record_validate(event)
51
51
  end
@@ -56,15 +56,15 @@ module BrainzLab
56
56
  def record_execution(event)
57
57
  payload = event.payload
58
58
  query = payload[:query]
59
- operation_name = query&.operation_name || "anonymous"
60
- operation_type = query&.selected_operation&.operation_type || "query"
59
+ operation_name = query&.operation_name || 'anonymous'
60
+ operation_type = query&.selected_operation&.operation_type || 'query'
61
61
  duration_ms = event.duration.round(2)
62
62
 
63
63
  # Add breadcrumb
64
64
  if BrainzLab.configuration.reflex_enabled
65
65
  BrainzLab::Reflex.add_breadcrumb(
66
66
  "GraphQL #{operation_type} #{operation_name}",
67
- category: "graphql.execute",
67
+ category: 'graphql.execute',
68
68
  level: payload[:errors]&.any? ? :error : :info,
69
69
  data: {
70
70
  operation_name: operation_name,
@@ -78,7 +78,7 @@ module BrainzLab
78
78
  # Record span
79
79
  record_span(
80
80
  name: "GraphQL #{operation_type} #{operation_name}",
81
- kind: "graphql",
81
+ kind: 'graphql',
82
82
  duration_ms: duration_ms,
83
83
  started_at: event.time,
84
84
  ended_at: event.end,
@@ -97,12 +97,12 @@ module BrainzLab
97
97
 
98
98
  def record_analyze(event)
99
99
  record_span(
100
- name: "GraphQL analyze",
101
- kind: "graphql",
100
+ name: 'GraphQL analyze',
101
+ kind: 'graphql',
102
102
  duration_ms: event.duration.round(2),
103
103
  started_at: event.time,
104
104
  ended_at: event.end,
105
- data: { phase: "analyze" }
105
+ data: { phase: 'analyze' }
106
106
  )
107
107
  rescue StandardError => e
108
108
  BrainzLab.debug_log("GraphQL analyze recording failed: #{e.message}")
@@ -110,12 +110,12 @@ module BrainzLab
110
110
 
111
111
  def record_validate(event)
112
112
  record_span(
113
- name: "GraphQL validate",
114
- kind: "graphql",
113
+ name: 'GraphQL validate',
114
+ kind: 'graphql',
115
115
  duration_ms: event.duration.round(2),
116
116
  started_at: event.time,
117
117
  ended_at: event.end,
118
- data: { phase: "validate" }
118
+ data: { phase: 'validate' }
119
119
  )
120
120
  rescue StandardError => e
121
121
  BrainzLab.debug_log("GraphQL validate recording failed: #{e.message}")
@@ -139,6 +139,7 @@ module BrainzLab
139
139
 
140
140
  def truncate_query(query)
141
141
  return nil unless query
142
+
142
143
  query.to_s[0, 2000]
143
144
  end
144
145
 
@@ -148,7 +149,7 @@ module BrainzLab
148
149
  scrub_fields = BrainzLab.configuration.scrub_fields
149
150
  variables.transform_values do |value|
150
151
  if scrub_fields.any? { |f| value.to_s.downcase.include?(f.to_s) }
151
- "[FILTERED]"
152
+ '[FILTERED]'
152
153
  else
153
154
  value
154
155
  end
@@ -163,19 +164,19 @@ module BrainzLab
163
164
  module Tracer
164
165
  def execute_query(query:)
165
166
  started_at = Time.now.utc
166
- operation_name = query.operation_name || "anonymous"
167
- operation_type = query.selected_operation&.operation_type || "query"
167
+ operation_name = query.operation_name || 'anonymous'
168
+ operation_type = query.selected_operation&.operation_type || 'query'
168
169
 
169
170
  result = super
170
171
 
171
172
  duration_ms = ((Time.now.utc - started_at) * 1000).round(2)
172
- has_errors = result.to_h["errors"]&.any?
173
+ has_errors = result.to_h['errors']&.any?
173
174
 
174
175
  # Add breadcrumb
175
176
  if BrainzLab.configuration.reflex_enabled
176
177
  BrainzLab::Reflex.add_breadcrumb(
177
178
  "GraphQL #{operation_type} #{operation_name}",
178
- category: "graphql.execute",
179
+ category: 'graphql.execute',
179
180
  level: has_errors ? :error : :info,
180
181
  data: {
181
182
  operation_name: operation_name,
@@ -191,7 +192,7 @@ module BrainzLab
191
192
  spans << {
192
193
  span_id: SecureRandom.uuid,
193
194
  name: "GraphQL #{operation_type} #{operation_name}",
194
- kind: "graphql",
195
+ kind: 'graphql',
195
196
  started_at: started_at,
196
197
  ended_at: Time.now.utc,
197
198
  duration_ms: duration_ms,
@@ -209,7 +210,7 @@ module BrainzLab
209
210
  if BrainzLab.configuration.reflex_enabled
210
211
  BrainzLab::Reflex.add_breadcrumb(
211
212
  "GraphQL #{operation_type} #{operation_name} failed",
212
- category: "graphql.error",
213
+ category: 'graphql.error',
213
214
  level: :error,
214
215
  data: { error: e.class.name }
215
216
  )
@@ -231,7 +232,7 @@ module BrainzLab
231
232
  spans << {
232
233
  span_id: SecureRandom.uuid,
233
234
  name: "GraphQL field #{field.owner.graphql_name}.#{field.graphql_name}",
234
- kind: "graphql.field",
235
+ kind: 'graphql.field',
235
236
  started_at: started_at,
236
237
  ended_at: Time.now.utc,
237
238
  duration_ms: duration_ms,
@@ -13,7 +13,7 @@ module BrainzLab
13
13
  ::HTTParty.singleton_class.prepend(Patch)
14
14
 
15
15
  @installed = true
16
- BrainzLab.debug_log("HTTParty instrumentation installed")
16
+ BrainzLab.debug_log('HTTParty instrumentation installed')
17
17
  end
18
18
 
19
19
  def installed?
@@ -26,14 +26,13 @@ module BrainzLab
26
26
  end
27
27
 
28
28
  module Patch
29
- def perform_request(http_method, path, options = {}, &block)
29
+ def perform_request(http_method, path, options = {}, &)
30
30
  return super unless should_track?(path, options)
31
31
 
32
32
  # Inject distributed tracing headers
33
33
  options = inject_trace_context(options)
34
34
 
35
35
  started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
36
- error_info = nil
37
36
 
38
37
  begin
39
38
  response = super
@@ -79,7 +78,7 @@ module BrainzLab
79
78
  method = extract_method_name(http_method)
80
79
  uri = parse_uri(path, options)
81
80
  url = uri ? sanitize_url(uri) : path.to_s
82
- host = uri&.host || "unknown"
81
+ host = uri&.host || 'unknown'
83
82
  request_path = uri&.path || path.to_s
84
83
  level = error || (status && status >= 400) ? :error : :info
85
84
 
@@ -87,7 +86,7 @@ module BrainzLab
87
86
  if BrainzLab.configuration.reflex_enabled
88
87
  BrainzLab::Reflex.add_breadcrumb(
89
88
  "#{method} #{url}",
90
- category: "http.httparty",
89
+ category: 'http.httparty',
91
90
  level: level,
92
91
  data: {
93
92
  method: method,
@@ -127,7 +126,7 @@ module BrainzLab
127
126
  span = {
128
127
  span_id: SecureRandom.uuid,
129
128
  name: "HTTP #{method} #{host}",
130
- kind: "http",
129
+ kind: 'http',
131
130
  started_at: Time.now.utc - (duration_ms / 1000.0),
132
131
  ended_at: Time.now.utc,
133
132
  duration_ms: duration_ms,
@@ -149,14 +148,14 @@ module BrainzLab
149
148
 
150
149
  def extract_method_name(http_method)
151
150
  case http_method.name
152
- when /Get$/ then "GET"
153
- when /Post$/ then "POST"
154
- when /Put$/ then "PUT"
155
- when /Patch$/ then "PATCH"
156
- when /Delete$/ then "DELETE"
157
- when /Head$/ then "HEAD"
158
- when /Options$/ then "OPTIONS"
159
- else http_method.name.split("::").last.upcase
151
+ when /Get$/ then 'GET'
152
+ when /Post$/ then 'POST'
153
+ when /Put$/ then 'PUT'
154
+ when /Patch$/ then 'PATCH'
155
+ when /Delete$/ then 'DELETE'
156
+ when /Head$/ then 'HEAD'
157
+ when /Options$/ then 'OPTIONS'
158
+ else http_method.name.split('::').last.upcase
160
159
  end
161
160
  end
162
161
 
@@ -26,7 +26,7 @@ module BrainzLab
26
26
  return unless installed_any
27
27
 
28
28
  @installed = true
29
- BrainzLab.debug_log("MongoDB instrumentation installed")
29
+ BrainzLab.debug_log('MongoDB instrumentation installed')
30
30
  end
31
31
 
32
32
  def installed?
@@ -51,9 +51,9 @@ module BrainzLab
51
51
 
52
52
  def install_mongoid!
53
53
  # For Mongoid 7+, use the APM module
54
- if ::Mongoid.respond_to?(:subscribe)
55
- ::Mongoid.subscribe(CommandSubscriber.new)
56
- end
54
+ return unless ::Mongoid.respond_to?(:subscribe)
55
+
56
+ ::Mongoid.subscribe(CommandSubscriber.new)
57
57
  end
58
58
  end
59
59
 
@@ -96,7 +96,7 @@ module BrainzLab
96
96
  def extract_collection(event)
97
97
  # Try to extract collection name from command
98
98
  cmd = event.command
99
- cmd["collection"] || cmd[event.command_name] || cmd.keys.first
99
+ cmd['collection'] || cmd[event.command_name] || cmd.keys.first
100
100
  rescue StandardError
101
101
  nil
102
102
  end
@@ -116,7 +116,7 @@ module BrainzLab
116
116
  if BrainzLab.configuration.reflex_enabled
117
117
  BrainzLab::Reflex.add_breadcrumb(
118
118
  "MongoDB #{command_name}",
119
- category: "mongodb",
119
+ category: 'mongodb',
120
120
  level: level,
121
121
  data: {
122
122
  command: command_name,
@@ -163,7 +163,7 @@ module BrainzLab
163
163
  span = {
164
164
  span_id: SecureRandom.uuid,
165
165
  name: "MongoDB #{command_name} #{collection}".strip,
166
- kind: "mongodb",
166
+ kind: 'mongodb',
167
167
  started_at: started_at,
168
168
  ended_at: Time.now.utc,
169
169
  duration_ms: duration_ms.round(2),
@@ -24,7 +24,7 @@ module BrainzLab
24
24
  end
25
25
 
26
26
  module Patch
27
- def request(req, body = nil, &block)
27
+ def request(req, body = nil, &)
28
28
  return super unless should_track?
29
29
 
30
30
  # Inject distributed tracing context into outgoing request headers
@@ -38,7 +38,7 @@ module BrainzLab
38
38
  response = super
39
39
  track_request(method, url, response.code.to_i, started_at)
40
40
  response
41
- rescue => e
41
+ rescue StandardError => e
42
42
  track_request(method, url, nil, started_at, e.class.name)
43
43
  raise
44
44
  end
@@ -69,9 +69,9 @@ module BrainzLab
69
69
  end
70
70
 
71
71
  def build_url(req)
72
- scheme = use_ssl? ? "https" : "http"
72
+ scheme = use_ssl? ? 'https' : 'http'
73
73
  port_str = if (use_ssl? && port == 443) || (!use_ssl? && port == 80)
74
- ""
74
+ ''
75
75
  else
76
76
  ":#{port}"
77
77
  end
@@ -86,7 +86,7 @@ module BrainzLab
86
86
  if BrainzLab.configuration.reflex_enabled
87
87
  BrainzLab::Reflex.add_breadcrumb(
88
88
  "#{method} #{url}",
89
- category: "http",
89
+ category: 'http',
90
90
  level: level,
91
91
  data: { method: method, url: url, status_code: status, duration_ms: duration_ms, error: error }.compact
92
92
  )
@@ -99,7 +99,7 @@ module BrainzLab
99
99
  method: method, url: url, status_code: status, duration_ms: duration_ms, error: error
100
100
  )
101
101
  end
102
- rescue => e
102
+ rescue StandardError => e
103
103
  # Don't let instrumentation errors crash the app
104
104
  BrainzLab.configuration.logger&.error("[BrainzLab] HTTP instrumentation error: #{e.message}")
105
105
  end