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
@@ -1,22 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "json"
5
- require "uri"
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'uri'
6
6
 
7
7
  module BrainzLab
8
8
  module Nerve
9
9
  class Client
10
10
  def initialize(config)
11
11
  @config = config
12
- @base_url = config.nerve_url || "https://nerve.brainzlab.ai"
12
+ @base_url = config.nerve_url || 'https://nerve.brainzlab.ai'
13
13
  end
14
14
 
15
15
  # Report a job execution
16
16
  def report_job(job_class:, job_id:, queue:, status:, started_at:, ended_at:, **attributes)
17
17
  response = request(
18
18
  :post,
19
- "/api/v1/jobs",
19
+ '/api/v1/jobs',
20
20
  body: {
21
21
  job_class: job_class,
22
22
  job_id: job_id,
@@ -31,7 +31,7 @@ module BrainzLab
31
31
 
32
32
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPCreated)
33
33
  rescue StandardError => e
34
- log_error("report_job", e)
34
+ log_error('report_job', e)
35
35
  false
36
36
  end
37
37
 
@@ -39,7 +39,7 @@ module BrainzLab
39
39
  def report_failure(job_class:, job_id:, queue:, error_class:, error_message:, backtrace: nil, **attributes)
40
40
  response = request(
41
41
  :post,
42
- "/api/v1/jobs/failures",
42
+ '/api/v1/jobs/failures',
43
43
  body: {
44
44
  job_class: job_class,
45
45
  job_id: job_id,
@@ -54,23 +54,23 @@ module BrainzLab
54
54
 
55
55
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPCreated)
56
56
  rescue StandardError => e
57
- log_error("report_failure", e)
57
+ log_error('report_failure', e)
58
58
  false
59
59
  end
60
60
 
61
61
  # Get job statistics
62
- def stats(queue: nil, job_class: nil, period: "1h")
62
+ def stats(queue: nil, job_class: nil, period: '1h')
63
63
  params = { period: period }
64
64
  params[:queue] = queue if queue
65
65
  params[:job_class] = job_class if job_class
66
66
 
67
- response = request(:get, "/api/v1/stats", params: params)
67
+ response = request(:get, '/api/v1/stats', params: params)
68
68
 
69
69
  return nil unless response.is_a?(Net::HTTPSuccess)
70
70
 
71
71
  JSON.parse(response.body, symbolize_names: true)
72
72
  rescue StandardError => e
73
- log_error("stats", e)
73
+ log_error('stats', e)
74
74
  nil
75
75
  end
76
76
 
@@ -80,27 +80,27 @@ module BrainzLab
80
80
  params[:queue] = queue if queue
81
81
  params[:status] = status if status
82
82
 
83
- response = request(:get, "/api/v1/jobs", params: params)
83
+ response = request(:get, '/api/v1/jobs', params: params)
84
84
 
85
85
  return [] unless response.is_a?(Net::HTTPSuccess)
86
86
 
87
87
  data = JSON.parse(response.body, symbolize_names: true)
88
88
  data[:jobs] || []
89
89
  rescue StandardError => e
90
- log_error("list_jobs", e)
90
+ log_error('list_jobs', e)
91
91
  []
92
92
  end
93
93
 
94
94
  # List queues
95
95
  def list_queues
96
- response = request(:get, "/api/v1/queues")
96
+ response = request(:get, '/api/v1/queues')
97
97
 
98
98
  return [] unless response.is_a?(Net::HTTPSuccess)
99
99
 
100
100
  data = JSON.parse(response.body, symbolize_names: true)
101
101
  data[:queues] || []
102
102
  rescue StandardError => e
103
- log_error("list_queues", e)
103
+ log_error('list_queues', e)
104
104
  []
105
105
  end
106
106
 
@@ -112,7 +112,7 @@ module BrainzLab
112
112
 
113
113
  JSON.parse(response.body, symbolize_names: true)
114
114
  rescue StandardError => e
115
- log_error("get_queue", e)
115
+ log_error('get_queue', e)
116
116
  nil
117
117
  end
118
118
 
@@ -121,7 +121,7 @@ module BrainzLab
121
121
  response = request(:post, "/api/v1/jobs/#{job_id}/retry")
122
122
  response.is_a?(Net::HTTPSuccess)
123
123
  rescue StandardError => e
124
- log_error("retry_job", e)
124
+ log_error('retry_job', e)
125
125
  false
126
126
  end
127
127
 
@@ -130,7 +130,7 @@ module BrainzLab
130
130
  response = request(:delete, "/api/v1/jobs/#{job_id}")
131
131
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPNoContent)
132
132
  rescue StandardError => e
133
- log_error("delete_job", e)
133
+ log_error('delete_job', e)
134
134
  false
135
135
  end
136
136
 
@@ -138,7 +138,7 @@ module BrainzLab
138
138
  def report_metrics(queue:, size:, latency_ms: nil, workers: nil)
139
139
  response = request(
140
140
  :post,
141
- "/api/v1/metrics",
141
+ '/api/v1/metrics',
142
142
  body: {
143
143
  queue: queue,
144
144
  size: size,
@@ -150,21 +150,21 @@ module BrainzLab
150
150
 
151
151
  response.is_a?(Net::HTTPSuccess)
152
152
  rescue StandardError => e
153
- log_error("report_metrics", e)
153
+ log_error('report_metrics', e)
154
154
  false
155
155
  end
156
156
 
157
157
  def provision(project_id:, app_name:)
158
158
  response = request(
159
159
  :post,
160
- "/api/v1/projects/provision",
160
+ '/api/v1/projects/provision',
161
161
  body: { project_id: project_id, app_name: app_name },
162
162
  use_service_key: true
163
163
  )
164
164
 
165
165
  response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPCreated)
166
166
  rescue StandardError => e
167
- log_error("provision", e)
167
+ log_error('provision', e)
168
168
  false
169
169
  end
170
170
 
@@ -173,34 +173,32 @@ module BrainzLab
173
173
  def request(method, path, headers: {}, body: nil, params: nil, use_service_key: false)
174
174
  uri = URI.parse("#{@base_url}#{path}")
175
175
 
176
- if params
177
- uri.query = URI.encode_www_form(params)
178
- end
176
+ uri.query = URI.encode_www_form(params) if params
179
177
 
180
178
  http = Net::HTTP.new(uri.host, uri.port)
181
- http.use_ssl = uri.scheme == "https"
179
+ http.use_ssl = uri.scheme == 'https'
182
180
  http.open_timeout = 5
183
181
  http.read_timeout = 10
184
182
 
185
183
  request = case method
186
- when :get
187
- Net::HTTP::Get.new(uri)
188
- when :post
189
- Net::HTTP::Post.new(uri)
190
- when :put
191
- Net::HTTP::Put.new(uri)
192
- when :delete
193
- Net::HTTP::Delete.new(uri)
194
- end
195
-
196
- request["Content-Type"] = "application/json"
197
- request["Accept"] = "application/json"
184
+ when :get
185
+ Net::HTTP::Get.new(uri)
186
+ when :post
187
+ Net::HTTP::Post.new(uri)
188
+ when :put
189
+ Net::HTTP::Put.new(uri)
190
+ when :delete
191
+ Net::HTTP::Delete.new(uri)
192
+ end
193
+
194
+ request['Content-Type'] = 'application/json'
195
+ request['Accept'] = 'application/json'
198
196
 
199
197
  if use_service_key
200
- request["X-Service-Key"] = @config.nerve_master_key || @config.secret_key
198
+ request['X-Service-Key'] = @config.nerve_master_key || @config.secret_key
201
199
  else
202
200
  auth_key = @config.nerve_api_key || @config.secret_key
203
- request["Authorization"] = "Bearer #{auth_key}" if auth_key
201
+ request['Authorization'] = "Bearer #{auth_key}" if auth_key
204
202
  end
205
203
 
206
204
  headers.each { |k, v| request[k] = v }
@@ -37,7 +37,7 @@ module BrainzLab
37
37
  end
38
38
 
39
39
  def detect_project_id
40
- ENV["BRAINZLAB_PROJECT_ID"]
40
+ ENV.fetch('BRAINZLAB_PROJECT_ID', nil)
41
41
  end
42
42
  end
43
43
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "nerve/client"
4
- require_relative "nerve/provisioner"
3
+ require_relative 'nerve/client'
4
+ require_relative 'nerve/provisioner'
5
5
 
6
6
  module BrainzLab
7
7
  module Nerve
@@ -32,7 +32,7 @@ module BrainzLab
32
32
  job_class: job_class,
33
33
  job_id: job_id,
34
34
  queue: queue,
35
- status: "completed",
35
+ status: 'completed',
36
36
  started_at: started_at,
37
37
  ended_at: ended_at,
38
38
  **attributes
@@ -69,7 +69,7 @@ module BrainzLab
69
69
  job_class: job_class,
70
70
  job_id: job_id,
71
71
  queue: queue,
72
- status: "running",
72
+ status: 'running',
73
73
  started_at: Time.now,
74
74
  ended_at: Time.now,
75
75
  **attributes
@@ -80,7 +80,7 @@ module BrainzLab
80
80
  # @param queue [String] Filter by queue (optional)
81
81
  # @param job_class [String] Filter by job class (optional)
82
82
  # @param period [String] Time period: "1h", "24h", "7d", "30d"
83
- def stats(queue: nil, job_class: nil, period: "1h")
83
+ def stats(queue: nil, job_class: nil, period: '1h')
84
84
  return nil unless enabled?
85
85
 
86
86
  ensure_provisioned!
@@ -160,7 +160,7 @@ module BrainzLab
160
160
  # # job work
161
161
  # end
162
162
  #
163
- def track(job_class:, job_id:, queue: "default", **attributes)
163
+ def track(job_class:, job_id:, queue: 'default', **attributes)
164
164
  started_at = Time.now
165
165
 
166
166
  begin
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "uri"
5
- require "json"
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
6
 
7
7
  module BrainzLab
8
8
  module Pulse
@@ -23,7 +23,7 @@ module BrainzLab
23
23
  if @config.pulse_buffer_size > 1
24
24
  buffer_trace(payload)
25
25
  else
26
- post("/api/v1/traces", payload)
26
+ post('/api/v1/traces', payload)
27
27
  end
28
28
  end
29
29
 
@@ -31,13 +31,13 @@ module BrainzLab
31
31
  return unless @config.pulse_enabled && @config.pulse_valid?
32
32
  return if payloads.empty?
33
33
 
34
- post("/api/v1/traces/batch", { traces: payloads })
34
+ post('/api/v1/traces/batch', { traces: payloads })
35
35
  end
36
36
 
37
37
  def send_metric(payload)
38
38
  return unless @config.pulse_enabled && @config.pulse_valid?
39
39
 
40
- post("/api/v1/metrics", payload)
40
+ post('/api/v1/metrics', payload)
41
41
  end
42
42
 
43
43
  def flush
@@ -79,9 +79,9 @@ module BrainzLab
79
79
  def post(path, body)
80
80
  uri = URI.join(@config.pulse_url, path)
81
81
  request = Net::HTTP::Post.new(uri)
82
- request["Content-Type"] = "application/json"
83
- request["Authorization"] = "Bearer #{@config.pulse_auth_key}"
84
- request["User-Agent"] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
82
+ request['Content-Type'] = 'application/json'
83
+ request['Authorization'] = "Bearer #{@config.pulse_auth_key}"
84
+ request['User-Agent'] = "brainzlab-sdk-ruby/#{BrainzLab::VERSION}"
85
85
  request.body = JSON.generate(body)
86
86
 
87
87
  execute_with_retry(uri, request)
@@ -94,7 +94,7 @@ module BrainzLab
94
94
  retries = 0
95
95
  begin
96
96
  http = Net::HTTP.new(uri.host, uri.port)
97
- http.use_ssl = uri.scheme == "https"
97
+ http.use_ssl = uri.scheme == 'https'
98
98
  http.open_timeout = 5
99
99
  http.read_timeout = 10
100
100
 
@@ -102,7 +102,11 @@ module BrainzLab
102
102
 
103
103
  case response.code.to_i
104
104
  when 200..299
105
- JSON.parse(response.body) rescue {}
105
+ begin
106
+ JSON.parse(response.body)
107
+ rescue StandardError
108
+ {}
109
+ end
106
110
  when 429, 500..599
107
111
  raise RetryableError, "Server error: #{response.code}"
108
112
  else
@@ -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