dead_bro 0.2.21 → 0.2.22

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: 96a0bc8cf707ea8af5d3bcd0be76fa02e28d09031c8a7897a311754cda8f7440
4
- data.tar.gz: 4a1407455415636db2858a28f0f77a8bb530d45fa916a359f85ae22f5f4294bb
3
+ metadata.gz: 14aa1509e04c9bf1848883cc5f2a12e7783e5ac4c123c9bcddde301948e30bfb
4
+ data.tar.gz: b3ec01b52a1e63efda701520a014f040fff96cedcbf36fe0827f4a7e892aac90
5
5
  SHA512:
6
- metadata.gz: 493d8d79e5eedd0d0443ddc3922ace02ed2f606220e7cff07e07484c9a628a85b54a5160551cb816630e06db34886e22ebae5c6c95e3697784b67a8c71b5b1ad
7
- data.tar.gz: 715064a097fadfb5ef97b96be9086f760f91efa004d3d339978f87ab87b6dce935ba5111c60c92a9f1849ec5a17a80e83efbd9f9cab031a963392f03a1055b2e
6
+ metadata.gz: 0c1f24b1718fa9aacf383d22e3b6982e76e7c5aa2c1ccf989d9c411bb0771b0a5fae60d9a780bbe845fac84cafc1a7f876b305005b9e5f3c07f82a7005b0775b
7
+ data.tar.gz: 469f652352cb2544b882b82dc528dced3e4725a34da033a14dd54b6e7742691a189eed1079dac1684e2da24ba587a955d4fcf3034c1c50f6a2f0d9bf514b2311
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeadBro
4
+ module CpuTracker
5
+ THREAD_KEY = :dead_bro_cpu_start
6
+
7
+ def self.start_request_tracking
8
+ Thread.current[THREAD_KEY] = thread_cpu_ms
9
+ end
10
+
11
+ def self.stop_request_tracking
12
+ before = Thread.current[THREAD_KEY]
13
+ return nil if before.nil?
14
+ after = thread_cpu_ms
15
+ return nil if after.nil?
16
+ (after - before).round(2)
17
+ ensure
18
+ Thread.current[THREAD_KEY] = nil
19
+ end
20
+
21
+ def self.thread_cpu_ms
22
+ Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond)
23
+ rescue
24
+ nil
25
+ end
26
+ end
27
+ end
@@ -67,6 +67,9 @@ module DeadBro
67
67
  # Start AR object instantiation counting for this request
68
68
  DeadBro::ArObjectTracker.start_request_tracking if defined?(DeadBro::ArObjectTracker)
69
69
 
70
+ # Start CPU time tracking for this request (thread-local clock)
71
+ DeadBro::CpuTracker.start_request_tracking if defined?(DeadBro::CpuTracker)
72
+
70
73
  # Start outgoing HTTP accumulation for this request
71
74
  Thread.current[:dead_bro_http_events] = []
72
75
 
@@ -106,6 +109,7 @@ module DeadBro
106
109
  Thread.current[DeadBro::GcTracker::THREAD_KEY] = nil if defined?(DeadBro::GcTracker)
107
110
  # Bypass stop_request_tracking intentionally — cleanup only, no return value needed here.
108
111
  Thread.current[DeadBro::ArObjectTracker::THREAD_KEY] = nil if defined?(DeadBro::ArObjectTracker)
112
+ Thread.current[DeadBro::CpuTracker::THREAD_KEY] = nil if defined?(DeadBro::CpuTracker)
109
113
  Thread.current[DeadBro::TRACKING_START_TIME_KEY] = nil
110
114
  end
111
115
 
@@ -72,6 +72,9 @@ module DeadBro
72
72
  # Stop AR object instantiation tracking
73
73
  ar_instantiation_count = defined?(DeadBro::ArObjectTracker) ? DeadBro::ArObjectTracker.stop_request_tracking : nil
74
74
 
75
+ # Stop CPU time tracking — thread CPU time consumed by this request
76
+ cpu_time_ms = defined?(DeadBro::CpuTracker) ? DeadBro::CpuTracker.stop_request_tracking : nil
77
+
75
78
  # Stop view rendering tracking and get collected view events
76
79
  view_events = DeadBro::ViewRenderingSubscriber.stop_request_tracking
77
80
  view_performance = DeadBro::ViewRenderingSubscriber.analyze_view_performance(view_events)
@@ -191,6 +194,7 @@ module DeadBro
191
194
  db_connection_checkouts: db_connection_stats[:checkouts],
192
195
  gc_pressure: gc_pressure,
193
196
  ar_instantiation_count: ar_instantiation_count,
197
+ cpu_time_ms: cpu_time_ms,
194
198
  logs: DeadBro.logger.logs
195
199
  }
196
200
  client.post_metric(event_name: name, payload: payload)
@@ -214,13 +218,14 @@ module DeadBro
214
218
  DeadBro::DbConnectionSubscriber.stop_request_tracking if defined?(DeadBro::DbConnectionSubscriber)
215
219
  DeadBro::GcTracker.stop_request_tracking if defined?(DeadBro::GcTracker)
216
220
  DeadBro::ArObjectTracker.stop_request_tracking if defined?(DeadBro::ArObjectTracker)
221
+ DeadBro::CpuTracker.stop_request_tracking if defined?(DeadBro::CpuTracker)
217
222
  rescue
218
223
  # Best effort — draining must never raise from the notifications callback.
219
224
  end
220
225
 
221
226
  def self.safe_path(data)
222
227
  path = data[:path] || (data[:request] && data[:request].path)
223
- path.to_s
228
+ sanitize_string(path)
224
229
  rescue
225
230
  ""
226
231
  end
@@ -266,11 +271,16 @@ module DeadBro
266
271
  {}
267
272
  end
268
273
 
274
+ def self.sanitize_string(str)
275
+ str.to_s.gsub("\x00", "")
276
+ end
277
+
269
278
  # Recursively truncate values to reasonable sizes to avoid huge payloads
270
279
  def self.truncate_value(value, max_str: 200, max_array: 20, max_hash_keys: 30)
271
280
  case value
272
281
  when String
273
- (value.length > max_str) ? value[0, max_str] + "…" : value
282
+ sanitized = sanitize_string(value)
283
+ (sanitized.length > max_str) ? sanitized[0, max_str] + "…" : sanitized
274
284
  when Numeric, TrueClass, FalseClass, NilClass
275
285
  value
276
286
  when Array
@@ -295,7 +305,7 @@ module DeadBro
295
305
  elsif data[:request].respond_to?(:env)
296
306
  ua = data[:request].env && data[:request].env["HTTP_USER_AGENT"]
297
307
  end
298
- return ua.to_s[0..200]
308
+ return sanitize_string(ua)[0..200]
299
309
  end
300
310
 
301
311
  # Fallback to headers object/hash if present in notification data
@@ -303,7 +313,7 @@ module DeadBro
303
313
  headers = data[:headers]
304
314
  if headers.respond_to?(:[])
305
315
  ua = headers["HTTP_USER_AGENT"] || headers["User-Agent"] || headers["user-agent"]
306
- return ua.to_s[0..200]
316
+ return sanitize_string(ua)[0..200]
307
317
  elsif headers.respond_to?(:to_h)
308
318
  h = begin
309
319
  headers.to_h
@@ -311,14 +321,14 @@ module DeadBro
311
321
  {}
312
322
  end
313
323
  ua = h["HTTP_USER_AGENT"] || h["User-Agent"] || h["user-agent"]
314
- return ua.to_s[0..200]
324
+ return sanitize_string(ua)[0..200]
315
325
  end
316
326
  end
317
327
 
318
328
  # Fallback to env hash if present in notification data
319
329
  if data[:env].is_a?(Hash)
320
330
  ua = data[:env]["HTTP_USER_AGENT"]
321
- return ua.to_s[0..200]
331
+ return sanitize_string(ua)[0..200]
322
332
  end
323
333
 
324
334
  ""
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeadBro
4
- VERSION = "0.2.21"
4
+ VERSION = "0.2.22"
5
5
  end
data/lib/dead_bro.rb CHANGED
@@ -20,6 +20,7 @@ module DeadBro
20
20
  autoload :LightweightMemoryTracker, "dead_bro/lightweight_memory_tracker"
21
21
  autoload :GcTracker, "dead_bro/gc_tracker"
22
22
  autoload :ArObjectTracker, "dead_bro/ar_object_tracker"
23
+ autoload :CpuTracker, "dead_bro/cpu_tracker"
23
24
  autoload :MemoryHelpers, "dead_bro/memory_helpers"
24
25
  autoload :JobSubscriber, "dead_bro/job_subscriber"
25
26
  autoload :JobSqlTrackingMiddleware, "dead_bro/job_sql_tracking_middleware"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dead_bro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.21
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuel Comsa
@@ -33,6 +33,7 @@ files:
33
33
  - lib/dead_bro/collectors/sample_store.rb
34
34
  - lib/dead_bro/collectors/system.rb
35
35
  - lib/dead_bro/configuration.rb
36
+ - lib/dead_bro/cpu_tracker.rb
36
37
  - lib/dead_bro/db_connection_subscriber.rb
37
38
  - lib/dead_bro/dispatcher.rb
38
39
  - lib/dead_bro/elasticsearch_subscriber.rb