apm_bro 0.1.17 → 0.1.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fde98f2cfbdbc149e9a10f3000a56c14fb35238bd09e0dba8b7cb17db7095b2
4
- data.tar.gz: 7b995dbae659d5e24982c1c2da7b2b50e644ca4b275bbc5fef410118bfc6a385
3
+ metadata.gz: 0c2d1fa177a670e4c599968669d284408d8e4e07feeae007bc3a7b4039dd3f69
4
+ data.tar.gz: a02724bba6a69bd2e66d1a8d893ee22d932d1f0bd2996f83b40cf0a0e4d6b257
5
5
  SHA512:
6
- metadata.gz: bcb1b5ce3f643b0b7ef971c3a219884892741664beefa28ae6c4111076e9eb393f8b10840ba655835061f9a481f07c35fc234f9e0bd787bcbceb150a08f0ba11
7
- data.tar.gz: 9f88694746c9ac3ba2dc463481ca26796bd04306817a44b44e7a596ea2c94aad4f7bb4d84c6cffa0470b614ba09b6da47379d8ce0325b3cc9e1f191fe949c830
6
+ metadata.gz: 44ef00e740c200bc47b45b032bed321a33e82f16973a695b19018226e57f879f11c4675cb082cbf324dfb441d298293555d43cfad1b0fb0421df661f6aeb2e7c
7
+ data.tar.gz: d907473bfbec4779f0658c27908ddd26551f175c61f26bac8661820d4ead6f8c963d9e1714e4d8161832076207cbcc09794bc854c2a67e54b336273079251e26
@@ -13,21 +13,12 @@ module ApmBro
13
13
  end
14
14
 
15
15
  def post_metric(event_name:, payload:)
16
- unless @configuration.enabled
17
- return
18
- end
16
+ return if @configuration.api_key.nil?
17
+ return unless @configuration.enabled
19
18
 
20
19
  # Check sampling rate - skip if not selected for sampling
21
- unless @configuration.should_sample?
22
- return
23
- end
24
-
25
- api_key = @configuration.resolve_api_key
26
-
27
- if api_key.nil?
28
- return
29
- end
30
-
20
+ return unless @configuration.should_sample?
21
+
31
22
  # Check circuit breaker before making request
32
23
  if @circuit_breaker && @configuration.circuit_breaker_enabled
33
24
  if @circuit_breaker.state == :open
@@ -41,7 +32,7 @@ module ApmBro
41
32
  end
42
33
 
43
34
  # Make the HTTP request (async)
44
- make_http_request(event_name, payload, api_key)
35
+ make_http_request(event_name, payload, @configuration.api_key)
45
36
 
46
37
  nil
47
38
  end
@@ -59,10 +50,9 @@ module ApmBro
59
50
  end
60
51
 
61
52
  def make_http_request(event_name, payload, api_key)
62
- endpoint_url = (@configuration.respond_to?(:ruby_dev) && @configuration.ruby_dev) ?
63
- "http://localhost:3100/apm/v1/metrics" :
64
- "https://www.deadbro.com/apm/v1/metrics"
65
-
53
+ use_staging = ENV["USE_STAGING_ENDPOINT"] && !ENV["USE_STAGING_ENDPOINT"].empty?
54
+ production_url = use_staging ? "https://deadbro.aberatii.com/apm/v1/metrics" : "https://www.deadbro.com/apm/v1/metrics"
55
+ endpoint_url = @configuration.ruby_dev ? "http://localhost:3100/apm/v1/metrics" : production_url
66
56
  uri = URI.parse(endpoint_url)
67
57
  http = Net::HTTP.new(uri.host, uri.port)
68
58
  http.use_ssl = (uri.scheme == "https")
@@ -2,9 +2,10 @@
2
2
 
3
3
  module ApmBro
4
4
  class Configuration
5
- DEFAULT_ENDPOINT_PATH = "/v1/metrics"
6
-
7
- attr_accessor :api_key, :endpoint_url, :open_timeout, :read_timeout, :enabled, :ruby_dev, :memory_tracking_enabled, :allocation_tracking_enabled, :circuit_breaker_enabled, :circuit_breaker_failure_threshold, :circuit_breaker_recovery_timeout, :circuit_breaker_retry_timeout, :sample_rate, :excluded_controllers, :excluded_jobs, :excluded_controller_actions, :exclusive_controller_actions, :exclusive_jobs, :deploy_id, :slow_query_threshold_ms, :explain_analyze_enabled
5
+ attr_accessor :api_key, :open_timeout, :read_timeout, :enabled, :ruby_dev, :memory_tracking_enabled,
6
+ :allocation_tracking_enabled, :circuit_breaker_enabled, :circuit_breaker_failure_threshold, :circuit_breaker_recovery_timeout,
7
+ :circuit_breaker_retry_timeout, :sample_rate, :excluded_controllers, :excluded_jobs,
8
+ :exclusive_controllers, :exclusive_jobs, :deploy_id, :slow_query_threshold_ms, :explain_analyze_enabled
8
9
 
9
10
  def initialize
10
11
  @api_key = nil
@@ -19,238 +20,62 @@ module ApmBro
19
20
  @circuit_breaker_failure_threshold = 3
20
21
  @circuit_breaker_recovery_timeout = 60 # seconds
21
22
  @circuit_breaker_retry_timeout = 300 # seconds
22
- @sample_rate = 100 # 100% sampling by default
23
+ @sample_rate = 100
23
24
  @excluded_controllers = []
24
25
  @excluded_jobs = []
25
- @excluded_controller_actions = []
26
- @exclusive_controller_actions = []
26
+ @exclusive_controllers = []
27
27
  @exclusive_jobs = []
28
28
  @deploy_id = resolve_deploy_id
29
29
  @slow_query_threshold_ms = 500 # Default: 500ms
30
30
  @explain_analyze_enabled = false # Enable EXPLAIN ANALYZE for slow queries by default
31
31
  end
32
32
 
33
- def resolve_api_key
34
- # Priority: explicit config -> Rails credentials/settings -> ENV
35
- return @api_key if present?(@api_key)
36
-
37
- if defined?(Rails)
38
- key = fetch_from_rails_settings
39
- return key if present?(key)
40
- end
41
-
42
- env_key = ENV["APM_BRO_API_KEY"]
43
- return env_key if present?(env_key)
44
-
45
- nil
33
+ def resolve_deploy_id
34
+ ENV["APM_BRO_DEPLOY_ID"] || ENV["GIT_REV"] || ENV["HEROKU_SLUG_COMMIT"] || ApmBro.process_deploy_id
46
35
  end
47
36
 
48
- def resolve_endpoint_url
49
- return @endpoint_url if present?(@endpoint_url)
50
-
51
- if defined?(Rails)
52
- host = fetch_from_rails_settings(%w[apm_bro host]) || ENV["APM_BRO_HOST"]
53
- if present?(host)
54
- return join_url(host, DEFAULT_ENDPOINT_PATH)
37
+ def excluded_controller?(controller_name, action_name = nil)
38
+ return false if @excluded_controllers.empty?
39
+
40
+ # If action_name is provided, check both controller#action patterns and controller-only patterns
41
+ if action_name
42
+ target = "#{controller_name}##{action_name}"
43
+ # Check controller#action patterns (patterns containing '#')
44
+ action_patterns = @excluded_controllers.select { |pat| pat.to_s.include?("#") }
45
+ if action_patterns.any? { |pat| match_name_or_pattern?(target, pat) }
46
+ return true
55
47
  end
48
+ # Check controller-only patterns (patterns without '#')
49
+ # If the controller itself is excluded, all its actions are excluded
50
+ controller_patterns = @excluded_controllers.reject { |pat| pat.to_s.include?("#") }
51
+ if controller_patterns.any? { |pat| match_name_or_pattern?(controller_name, pat) }
52
+ return true
53
+ end
54
+ return false
56
55
  end
57
-
58
- ENV["APM_BRO_ENDPOINT_URL"]
59
- end
60
-
61
- def resolve_sample_rate
62
- # Priority: explicit config -> Rails credentials/settings -> ENV -> default
63
- return @sample_rate if present?(@sample_rate)
64
-
65
- if defined?(Rails)
66
- rate = fetch_from_rails_settings(%w[apm_bro sample_rate])
67
- return rate if present?(rate)
68
- end
69
-
70
- env_rate = ENV["APM_BRO_SAMPLE_RATE"]
71
- return env_rate.to_i if present?(env_rate) && env_rate.match?(/^\d+$/)
72
-
73
- 100 # default
74
- end
75
-
76
- def resolve_deploy_id
77
- # Priority: explicit config -> Rails settings/credentials -> ENV -> random UUID
78
- return @deploy_id if present?(@deploy_id)
79
-
80
- if defined?(Rails)
81
- val = fetch_from_rails_settings(%w[apm_bro deploy_id])
82
- return val if present?(val)
83
- end
84
-
85
- # Prefer explicit env var, then common platform-specific var
86
- apm_bro_deploy_id = ENV["APM_BRO_DEPLOY_ID"]
87
- return apm_bro_deploy_id if present?(apm_bro_deploy_id)
88
-
89
- env_val = ENV["GIT_REV"]
90
- return env_val if present?(env_val)
91
-
92
- heroku_val = ENV["HEROKU_SLUG_COMMIT"]
93
- return heroku_val if present?(heroku_val)
94
-
95
- # Fall back to a process-stable ID
96
- ApmBro.process_deploy_id
97
- end
98
-
99
- def excluded_controller?(controller_name)
100
- list = resolve_excluded_controllers
101
- return false if list.nil? || list.empty?
102
- list.any? { |pat| match_name_or_pattern?(controller_name, pat) }
56
+
57
+ # When action_name is nil, only check controller-only patterns (no #)
58
+ controller_patterns = @excluded_controllers.reject { |pat| pat.to_s.include?("#") }
59
+ return false if controller_patterns.empty?
60
+ controller_patterns.any? { |pat| match_name_or_pattern?(controller_name, pat) }
103
61
  end
104
62
 
105
63
  def excluded_job?(job_class_name)
106
- list = resolve_excluded_jobs
107
- return false if list.nil? || list.empty?
108
- list.any? { |pat| match_name_or_pattern?(job_class_name, pat) }
64
+ return false if @excluded_jobs.empty?
65
+ @excluded_jobs.any? { |pat| match_name_or_pattern?(job_class_name, pat) }
109
66
  end
110
67
 
111
68
  def exclusive_job?(job_class_name)
112
- list = resolve_exclusive_jobs
113
- return true if list.nil? || list.empty? # If not defined, allow all (default behavior)
114
- list.any? { |pat| match_name_or_pattern?(job_class_name, pat) }
69
+ return true if @exclusive_jobs.empty? # If not defined, allow all (default behavior)
70
+ @exclusive_jobs.any? { |pat| match_name_or_pattern?(job_class_name, pat) }
115
71
  end
116
72
 
117
- def excluded_controller_action?(controller_name, action_name)
118
- list = resolve_excluded_controller_actions
119
- return false if list.nil? || list.empty?
73
+ def exclusive_controller?(controller_name, action_name)
74
+ return true if @exclusive_controllers.empty? # If not defined, allow all (default behavior)
120
75
  target = "#{controller_name}##{action_name}"
121
- list.any? { |pat| match_name_or_pattern?(target, pat) }
122
- end
123
-
124
- def exclusive_controller_action?(controller_name, action_name)
125
- list = resolve_exclusive_controller_actions
126
- return true if list.nil? || list.empty? # If not defined, allow all (default behavior)
127
- target = "#{controller_name}##{action_name}"
128
- list.any? { |pat| match_name_or_pattern?(target, pat) }
129
- end
130
-
131
- def resolve_excluded_controller_actions
132
- # Collect patterns from @excluded_controller_actions
133
- patterns = []
134
- if @excluded_controller_actions && !@excluded_controller_actions.empty?
135
- patterns.concat(Array(@excluded_controller_actions))
136
- end
137
-
138
- # Also check @excluded_controllers for patterns containing '#' (controller action patterns)
139
- if @excluded_controllers && !@excluded_controllers.empty?
140
- action_patterns = Array(@excluded_controllers).select { |pat| pat.to_s.include?("#") }
141
- patterns.concat(action_patterns)
142
- end
143
-
144
- return patterns if !patterns.empty?
145
-
146
- if defined?(Rails)
147
- list = fetch_from_rails_settings(%w[apm_bro excluded_controller_actions])
148
- if list
149
- rails_patterns = Array(list)
150
- # Also check excluded_controllers from Rails settings for action patterns
151
- controllers_list = fetch_from_rails_settings(%w[apm_bro excluded_controllers])
152
- if controllers_list
153
- action_patterns = Array(controllers_list).select { |pat| pat.to_s.include?("#") }
154
- rails_patterns.concat(action_patterns)
155
- end
156
- return rails_patterns if !rails_patterns.empty?
157
- end
158
- end
159
-
160
- env = ENV["APM_BRO_EXCLUDED_CONTROLLER_ACTIONS"]
161
- if env && !env.strip.empty?
162
- env_patterns = env.split(",").map(&:strip)
163
- # Also check excluded_controllers env var for action patterns
164
- controllers_env = ENV["APM_BRO_EXCLUDED_CONTROLLERS"]
165
- if controllers_env && !controllers_env.strip.empty?
166
- action_patterns = controllers_env.split(",").map(&:strip).select { |pat| pat.include?("#") }
167
- env_patterns.concat(action_patterns)
168
- end
169
- return env_patterns if !env_patterns.empty?
170
- end
171
-
172
- []
173
- end
174
-
175
- def resolve_excluded_controllers
176
- return @excluded_controllers if @excluded_controllers && !@excluded_controllers.empty?
177
-
178
- if defined?(Rails)
179
- list = fetch_from_rails_settings(%w[apm_bro excluded_controllers])
180
- return Array(list) if list
181
- end
182
-
183
- env = ENV["APM_BRO_EXCLUDED_CONTROLLERS"]
184
- return env.split(",").map(&:strip) if env && !env.strip.empty?
185
-
186
- []
187
- end
188
-
189
- def resolve_excluded_jobs
190
- return @excluded_jobs if @excluded_jobs && !@excluded_jobs.empty?
191
-
192
- if defined?(Rails)
193
- list = fetch_from_rails_settings(%w[apm_bro excluded_jobs])
194
- return Array(list) if list
195
- end
196
-
197
- env = ENV["APM_BRO_EXCLUDED_JOBS"]
198
- return env.split(",").map(&:strip) if env && !env.strip.empty?
199
-
200
- []
201
- end
202
-
203
- def resolve_exclusive_controller_actions
204
- # Collect patterns from @exclusive_controller_actions
205
- patterns = []
206
- if @exclusive_controller_actions && !@exclusive_controller_actions.empty?
207
- patterns.concat(Array(@exclusive_controller_actions))
208
- end
209
-
210
- return patterns if !patterns.empty?
211
-
212
- if defined?(Rails)
213
- list = fetch_from_rails_settings(%w[apm_bro exclusive_controller_actions])
214
- if list
215
- rails_patterns = Array(list)
216
- return rails_patterns if !rails_patterns.empty?
217
- end
218
- end
219
-
220
- env = ENV["APM_BRO_EXCLUSIVE_CONTROLLER_ACTIONS"]
221
- if env && !env.strip.empty?
222
- env_patterns = env.split(",").map(&:strip)
223
- return env_patterns if !env_patterns.empty?
224
- end
225
-
226
- []
76
+ @exclusive_controllers.any? { |pat| match_name_or_pattern?(target, pat) }
227
77
  end
228
78
 
229
- def resolve_exclusive_jobs
230
- # Collect patterns from @exclusive_jobs
231
- patterns = []
232
- if @exclusive_jobs && !@exclusive_jobs.empty?
233
- patterns.concat(Array(@exclusive_jobs))
234
- end
235
-
236
- return patterns if !patterns.empty?
237
-
238
- if defined?(Rails)
239
- list = fetch_from_rails_settings(%w[apm_bro exclusive_jobs])
240
- if list
241
- rails_patterns = Array(list)
242
- return rails_patterns if !rails_patterns.empty?
243
- end
244
- end
245
-
246
- env = ENV["APM_BRO_EXCLUSIVE_JOBS"]
247
- if env && !env.strip.empty?
248
- env_patterns = env.split(",").map(&:strip)
249
- return env_patterns if !env_patterns.empty?
250
- end
251
-
252
- []
253
- end
254
79
 
255
80
  def should_sample?
256
81
  sample_rate = resolve_sample_rate
@@ -260,13 +85,34 @@ module ApmBro
260
85
  # Generate random number 1-100 and check if it's within sample rate
261
86
  rand(1..100) <= sample_rate
262
87
  end
88
+
89
+ def resolve_sample_rate
90
+ return @sample_rate unless @sample_rate.nil?
91
+
92
+ if ENV["APM_BRO_SAMPLE_RATE"]
93
+ env_value = ENV["APM_BRO_SAMPLE_RATE"].to_s.strip
94
+ # Validate that it's a valid integer string
95
+ if env_value.match?(/^\d+$/)
96
+ parsed = env_value.to_i
97
+ # Ensure it's in valid range (0-100)
98
+ (parsed >= 0 && parsed <= 100) ? parsed : 100
99
+ else
100
+ 100 # Invalid format, fall back to default
101
+ end
102
+ else
103
+ 100 # default
104
+ end
105
+ end
106
+
107
+ def resolve_api_key
108
+ return @api_key unless @api_key.nil?
109
+
110
+ ENV["APM_BRO_API_KEY"]
111
+ end
263
112
 
264
113
  def sample_rate=(value)
265
114
  # Allow nil to use default/resolved value
266
- if value.nil?
267
- @sample_rate = nil
268
- return
269
- end
115
+ return @sample_rate = nil if value.nil?
270
116
 
271
117
  # Allow 0 to disable sampling, or 1-100 for percentage
272
118
  unless value.is_a?(Integer) && value >= 0 && value <= 100
@@ -277,10 +123,6 @@ module ApmBro
277
123
 
278
124
  private
279
125
 
280
- def present?(value)
281
- !(value.nil? || (value.respond_to?(:empty?) && value.empty?))
282
- end
283
-
284
126
  def match_name_or_pattern?(name, pattern)
285
127
  return false if name.nil? || pattern.nil?
286
128
  pat = pattern.to_s
@@ -300,79 +142,5 @@ module ApmBro
300
142
  false
301
143
  end
302
144
 
303
- def fetch_from_rails_settings(path_keys = ["apm_bro", "api_key"])
304
- # Try Rails.application.config_for(:apm_bro)
305
- begin
306
- if Rails.respond_to?(:application) && Rails.application.respond_to?(:config_for)
307
- config = begin
308
- Rails.application.config_for(:apm_bro)
309
- rescue
310
- nil
311
- end
312
- if config && config.is_a?(Hash)
313
- return dig_hash(config, *Array(path_keys))
314
- end
315
- end
316
- rescue
317
- end
318
-
319
- # Try Rails.application.credentials
320
- begin
321
- creds = Rails.application.credentials if Rails.respond_to?(:application)
322
- if creds
323
- # credentials.apm_bro[:api_key] or credentials[:apm_bro][:api_key]
324
- value = dig_credentials(creds, *Array(path_keys))
325
- return value if present?(value)
326
- end
327
- rescue
328
- end
329
-
330
- # Try Rails.application.config.x.apm_bro.api_key
331
- begin
332
- x = Rails.application.config.x if Rails.respond_to?(:application)
333
- if x && x.respond_to?(:apm_bro)
334
- config_x = x.apm_bro
335
- return config_x.public_send(Array(path_keys).last) if config_x.respond_to?(Array(path_keys).last)
336
- end
337
- rescue
338
- end
339
-
340
- nil
341
- end
342
-
343
- def dig_hash(hash, *keys)
344
- keys.reduce(hash) do |memo, key|
345
- break nil unless memo.is_a?(Hash)
346
- memo[key.to_s] || memo[key.to_sym]
347
- end
348
- end
349
-
350
- def dig_credentials(creds, *keys)
351
- # Rails credentials can behave like hashes or use methods
352
- current = creds
353
- keys.each do |key|
354
- if current.respond_to?(:[]) && current[key].nil? && current[key.to_sym].nil?
355
- if current.respond_to?(key)
356
- current = current.public_send(key)
357
- elsif current.respond_to?(key.to_sym)
358
- current = current.public_send(key.to_sym)
359
- else
360
- return nil
361
- end
362
- else
363
- current = current[key] || current[key.to_sym]
364
- end
365
- return nil if current.nil?
366
- end
367
- current
368
- end
369
-
370
- def join_url(base, path)
371
- base = base.to_s
372
- path = path.to_s
373
- base = base.chomp("/")
374
- path = "/#{path}" unless path.start_with?("/")
375
- base + path
376
- end
377
145
  end
378
146
  end
@@ -6,9 +6,9 @@ module ApmBro
6
6
  class ErrorMiddleware
7
7
  EVENT_NAME = "exception.uncaught"
8
8
 
9
- def initialize(app, client: Client.new)
9
+ def initialize(app, client = nil)
10
10
  @app = app
11
- @client = client
11
+ @client = client || ApmBro.client
12
12
  end
13
13
 
14
14
  def call(env)
@@ -38,7 +38,7 @@ module ApmBro
38
38
 
39
39
  # Skip instrumentation for our own APM endpoint to prevent infinite loops,
40
40
  # but do NOT alter the original method's return value/control flow.
41
- skip_instrumentation = uri && (uri.to_s.include?("localhost") || uri.to_s.include?("uptime.aberatii.com"))
41
+ skip_instrumentation = uri && (uri.to_s.include?("localhost") || uri.to_s.include?("aberatii.com"))
42
42
 
43
43
  unless skip_instrumentation
44
44
  payload = {
@@ -85,7 +85,7 @@ module ApmBro
85
85
 
86
86
  # Skip instrumentation for our own APM endpoint to prevent infinite loops,
87
87
  # but do NOT alter the original method's return value/control flow.
88
- skip_instrumentation = req_url && req_url.include?("localhost:3100/apm/v1/metrics")
88
+ skip_instrumentation = req_url && (req_url.include?("localhost:3100/apm/v1/metrics") || req_url.include?("deadbro.aberatii.com/apm/v1/metrics"))
89
89
 
90
90
  unless skip_instrumentation
91
91
  payload = {
@@ -10,26 +10,16 @@ end
10
10
  if defined?(Rails) && defined?(Rails::Railtie)
11
11
  module ApmBro
12
12
  class Railtie < ::Rails::Railtie
13
- initializer "apm_bro.configure" do |_app|
14
- # Allow host app to set config in Rails config, credentials, or ENV.
15
- # If host app sets config.x.apm_bro, mirror into gem configuration.
16
-
17
- if Rails.application.config.x.respond_to?(:apm_bro)
18
- xcfg = Rails.application.config.x.apm_bro
19
- ApmBro.configure do |cfg|
20
- cfg.api_key = xcfg.api_key if xcfg.respond_to?(:api_key)
21
- cfg.enabled = xcfg.enabled if xcfg.respond_to?(:enabled)
22
- end
23
- end
24
- rescue
25
- end
26
13
 
27
14
  initializer "apm_bro.subscribe" do |app|
28
15
  app.config.after_initialize do
29
- ApmBro::Subscriber.subscribe!(client: ApmBro::Client.new)
16
+ # Use the shared Client instance for all subscribers
17
+ shared_client = ApmBro.client
18
+
19
+ ApmBro::Subscriber.subscribe!(client: shared_client)
30
20
  # Install outgoing HTTP instrumentation
31
21
  require "apm_bro/http_instrumentation"
32
- ApmBro::HttpInstrumentation.install!(client: ApmBro::Client.new)
22
+ ApmBro::HttpInstrumentation.install!(client: shared_client)
33
23
 
34
24
  # Install SQL query tracking
35
25
  require "apm_bro/sql_subscriber"
@@ -45,7 +35,7 @@ if defined?(Rails) && defined?(Rails::Railtie)
45
35
 
46
36
  # Install view rendering tracking
47
37
  require "apm_bro/view_rendering_subscriber"
48
- ApmBro::ViewRenderingSubscriber.subscribe!(client: ApmBro::Client.new)
38
+ ApmBro::ViewRenderingSubscriber.subscribe!(client: shared_client)
49
39
 
50
40
  # Install lightweight memory tracking (default)
51
41
  require "apm_bro/lightweight_memory_tracker"
@@ -55,7 +45,7 @@ if defined?(Rails) && defined?(Rails::Railtie)
55
45
  # Install detailed memory tracking only if enabled
56
46
  if ApmBro.configuration.allocation_tracking_enabled
57
47
  require "apm_bro/memory_tracking_subscriber"
58
- ApmBro::MemoryTrackingSubscriber.subscribe!(client: ApmBro::Client.new)
48
+ ApmBro::MemoryTrackingSubscriber.subscribe!(client: shared_client)
59
49
  end
60
50
 
61
51
  # Install job tracking if ActiveJob is available
@@ -63,7 +53,7 @@ if defined?(Rails) && defined?(Rails::Railtie)
63
53
  require "apm_bro/job_subscriber"
64
54
  require "apm_bro/job_sql_tracking_middleware"
65
55
  ApmBro::JobSqlTrackingMiddleware.subscribe!
66
- ApmBro::JobSubscriber.subscribe!(client: ApmBro::Client.new)
56
+ ApmBro::JobSubscriber.subscribe!(client: shared_client)
67
57
  end
68
58
  rescue
69
59
  # Never raise in Railtie init
@@ -73,13 +63,16 @@ if defined?(Rails) && defined?(Rails::Railtie)
73
63
  # Insert Rack middleware early enough to observe uncaught exceptions
74
64
  initializer "apm_bro.middleware" do |app|
75
65
  require "apm_bro/error_middleware"
66
+
67
+ # Use the shared Client instance for the middleware
68
+ shared_client = ApmBro.client
76
69
 
77
70
  if defined?(::ActionDispatch::DebugExceptions)
78
- app.config.middleware.insert_before(::ActionDispatch::DebugExceptions, ::ApmBro::ErrorMiddleware)
71
+ app.config.middleware.insert_before(::ActionDispatch::DebugExceptions, ::ApmBro::ErrorMiddleware, shared_client)
79
72
  elsif defined?(::ActionDispatch::ShowExceptions)
80
- app.config.middleware.insert_before(::ActionDispatch::ShowExceptions, ::ApmBro::ErrorMiddleware)
73
+ app.config.middleware.insert_before(::ActionDispatch::ShowExceptions, ::ApmBro::ErrorMiddleware, shared_client)
81
74
  else
82
- app.config.middleware.use(::ApmBro::ErrorMiddleware)
75
+ app.config.middleware.use(::ApmBro::ErrorMiddleware, shared_client)
83
76
  end
84
77
  rescue
85
78
  # Never raise in Railtie init
@@ -12,37 +12,31 @@ module ApmBro
12
12
 
13
13
  # Start SQL tracking for this request
14
14
  if defined?(ApmBro::SqlSubscriber)
15
- puts "Starting SQL tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
16
15
  ApmBro::SqlSubscriber.start_request_tracking
17
16
  end
18
17
 
19
18
  # Start cache tracking for this request
20
19
  if defined?(ApmBro::CacheSubscriber)
21
- puts "Starting cache tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
22
20
  ApmBro::CacheSubscriber.start_request_tracking
23
21
  end
24
22
 
25
23
  # Start Redis tracking for this request
26
24
  if defined?(ApmBro::RedisSubscriber)
27
- puts "Starting redis tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
28
25
  ApmBro::RedisSubscriber.start_request_tracking
29
26
  end
30
27
 
31
28
  # Start view rendering tracking for this request
32
29
  if defined?(ApmBro::ViewRenderingSubscriber)
33
- puts "Starting view rendering tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
34
30
  ApmBro::ViewRenderingSubscriber.start_request_tracking
35
31
  end
36
32
 
37
33
  # Start lightweight memory tracking for this request
38
34
  if defined?(ApmBro::LightweightMemoryTracker)
39
- puts "Starting lightweight memory tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
40
35
  ApmBro::LightweightMemoryTracker.start_request_tracking
41
36
  end
42
37
 
43
38
  # Start detailed memory tracking when allocation tracking is enabled
44
39
  if ApmBro.configuration.allocation_tracking_enabled && defined?(ApmBro::MemoryTrackingSubscriber)
45
- puts "Starting detailed memory tracking for request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
46
40
  ApmBro::MemoryTrackingSubscriber.start_request_tracking
47
41
  end
48
42
 
@@ -13,11 +13,13 @@ module ApmBro
13
13
  begin
14
14
  controller_name = data[:controller].to_s
15
15
  action_name = data[:action].to_s
16
- if ApmBro.configuration.excluded_controller_action?(controller_name, action_name)
16
+ if ApmBro.configuration.excluded_controller?(controller_name, action_name)
17
+ puts "excluded controller"
17
18
  next
18
19
  end
19
20
  # If exclusive_controller_actions is defined and not empty, only track matching actions
20
- unless ApmBro.configuration.exclusive_controller_action?(controller_name, action_name)
21
+ unless ApmBro.configuration.exclusive_controller?(controller_name, action_name)
22
+ puts "exclusive controller"
21
23
  next
22
24
  end
23
25
  rescue
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApmBro
4
- VERSION = "0.1.17"
4
+ VERSION = "0.1.19"
5
5
  end
data/lib/apm_bro.rb CHANGED
@@ -33,9 +33,15 @@ module ApmBro
33
33
  def self.configuration
34
34
  @configuration ||= Configuration.new
35
35
  end
36
-
36
+
37
37
  def self.reset_configuration!
38
- @configuration = Configuration.new
38
+ @configuration = nil
39
+ @client = nil
40
+ end
41
+
42
+ # Returns a shared Client instance for use across the application
43
+ def self.client
44
+ @client ||= Client.new
39
45
  end
40
46
 
41
47
  # Returns a process-stable deploy identifier used when none is configured.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apm_bro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuel Comsa