dead_bro 0.2.5 → 0.2.6
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 +4 -4
- data/lib/dead_bro/memory_tracking_subscriber.rb +47 -3
- data/lib/dead_bro/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e977f41766dfbcf7ca52cf14aafb217595f35860746a553bd9386b1ddfe7797
|
|
4
|
+
data.tar.gz: 24858e179f45181d6d144352347ed3f760a19abe53cead83c80eb4644e281f39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7310571657927f6404088b2605d710cb9e107d5e63231cddcf785ffc9cc22a78ff634d5bc5969e34d08e634ed0cdc46f85f8f2d6937bc05ebe9af14b00c4968c
|
|
7
|
+
data.tar.gz: eaaec05db2cdf1d2da03cfa873c333286d891e33cb2e37d6b347b319a3ae8481f142182d87c3ce20bd2990829075aa236e52c9f52388d2799fc862b1511ceabd
|
|
@@ -6,6 +6,7 @@ module DeadBro
|
|
|
6
6
|
class MemoryTrackingSubscriber
|
|
7
7
|
# Object allocation events
|
|
8
8
|
ALLOCATION_EVENT = "object_allocations.active_support"
|
|
9
|
+
PROCESS_ACTION_EVENT = "process_action.action_controller"
|
|
9
10
|
|
|
10
11
|
THREAD_LOCAL_KEY = :dead_bro_memory_events
|
|
11
12
|
# Consider objects larger than this many bytes as "large"
|
|
@@ -28,6 +29,23 @@ module DeadBro
|
|
|
28
29
|
next unless rand < ALLOCATION_SAMPLING_RATE
|
|
29
30
|
track_allocation(data, started, finished)
|
|
30
31
|
end
|
|
32
|
+
|
|
33
|
+
# Subscribe to process_action to capture request-level allocation counters
|
|
34
|
+
ActiveSupport::Notifications.subscribe(PROCESS_ACTION_EVENT) do |*args|
|
|
35
|
+
event = if args.length == 1 && args.first.is_a?(ActiveSupport::Notifications::Event)
|
|
36
|
+
args.first
|
|
37
|
+
else
|
|
38
|
+
ActiveSupport::Notifications::Event.new(*args)
|
|
39
|
+
end
|
|
40
|
+
allocations = event.respond_to?(:allocations) ? event.allocations : event.payload[:allocations]
|
|
41
|
+
allocated_bytes = event.respond_to?(:allocated_bytes) ? event.allocated_bytes : event.payload[:allocated_bytes]
|
|
42
|
+
next unless allocations || allocated_bytes
|
|
43
|
+
|
|
44
|
+
record_request_allocations(
|
|
45
|
+
allocations: allocations,
|
|
46
|
+
allocated_bytes: allocated_bytes
|
|
47
|
+
)
|
|
48
|
+
end
|
|
31
49
|
rescue
|
|
32
50
|
# Allocation tracking might not be available in all Ruby versions
|
|
33
51
|
end
|
|
@@ -44,9 +62,10 @@ module DeadBro
|
|
|
44
62
|
allocations: [],
|
|
45
63
|
memory_snapshots: [],
|
|
46
64
|
large_objects: [],
|
|
65
|
+
request_allocations: nil,
|
|
47
66
|
gc_before: gc_stats,
|
|
48
67
|
memory_before: memory_usage_mb,
|
|
49
|
-
start_time: Time.now.
|
|
68
|
+
start_time: Time.now.to_f,
|
|
50
69
|
object_counts_before: count_objects_snapshot
|
|
51
70
|
}
|
|
52
71
|
end
|
|
@@ -58,7 +77,7 @@ module DeadBro
|
|
|
58
77
|
if events
|
|
59
78
|
events[:gc_after] = gc_stats
|
|
60
79
|
events[:memory_after] = memory_usage_mb
|
|
61
|
-
events[:end_time] = Time.now.
|
|
80
|
+
events[:end_time] = Time.now.to_f
|
|
62
81
|
events[:duration_seconds] = events[:end_time] - events[:start_time]
|
|
63
82
|
events[:object_counts_after] = count_objects_snapshot
|
|
64
83
|
|
|
@@ -71,6 +90,16 @@ module DeadBro
|
|
|
71
90
|
events || {}
|
|
72
91
|
end
|
|
73
92
|
|
|
93
|
+
# Record request-level allocation counters from Rails instrumentation.
|
|
94
|
+
def self.record_request_allocations(allocations:, allocated_bytes:)
|
|
95
|
+
return unless Thread.current[THREAD_LOCAL_KEY]
|
|
96
|
+
|
|
97
|
+
Thread.current[THREAD_LOCAL_KEY][:request_allocations] = {
|
|
98
|
+
allocations: allocations,
|
|
99
|
+
allocated_bytes: allocated_bytes
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
74
103
|
def self.track_allocation(data, started, finished)
|
|
75
104
|
return unless Thread.current[THREAD_LOCAL_KEY]
|
|
76
105
|
|
|
@@ -122,6 +151,7 @@ module DeadBro
|
|
|
122
151
|
allocations = memory_events[:allocations] || []
|
|
123
152
|
large_objects = memory_events[:large_objects] || []
|
|
124
153
|
snapshots = memory_events[:memory_snapshots] || []
|
|
154
|
+
request_allocations = memory_events[:request_allocations]
|
|
125
155
|
|
|
126
156
|
# Calculate memory growth
|
|
127
157
|
memory_growth = 0
|
|
@@ -132,6 +162,19 @@ module DeadBro
|
|
|
132
162
|
# Calculate allocation totals
|
|
133
163
|
total_allocations = allocations.sum { |a| a[:count] }
|
|
134
164
|
total_allocated_size = allocations.sum { |a| a[:size] }
|
|
165
|
+
if request_allocations
|
|
166
|
+
total_allocated_size = request_allocations[:allocated_bytes].to_i if total_allocated_size.zero?
|
|
167
|
+
end
|
|
168
|
+
gc_allocations = nil
|
|
169
|
+
if memory_events[:gc_before] && memory_events[:gc_after]
|
|
170
|
+
gc_allocations = (memory_events[:gc_after][:total_allocated_objects] || 0) -
|
|
171
|
+
(memory_events[:gc_before][:total_allocated_objects] || 0)
|
|
172
|
+
end
|
|
173
|
+
if gc_allocations.to_i > 0
|
|
174
|
+
total_allocations = gc_allocations
|
|
175
|
+
elsif total_allocations.zero? && request_allocations
|
|
176
|
+
total_allocations = request_allocations[:allocations].to_i
|
|
177
|
+
end
|
|
135
178
|
|
|
136
179
|
# Group allocations by class
|
|
137
180
|
allocations_by_class = allocations.group_by { |a| a[:class_name] }
|
|
@@ -174,7 +217,8 @@ module DeadBro
|
|
|
174
217
|
(total_allocations.to_f / memory_events[:duration_seconds]).round(2) : 0,
|
|
175
218
|
top_allocating_classes: top_allocating_classes.map { |class_name, data|
|
|
176
219
|
{
|
|
177
|
-
|
|
220
|
+
class: class_name,
|
|
221
|
+
name: class_name,
|
|
178
222
|
count: data[:count],
|
|
179
223
|
size: data[:size],
|
|
180
224
|
size_mb: (data[:size] / 1_000_000.0).round(2)
|
data/lib/dead_bro/version.rb
CHANGED