dead_bro 0.2.30 → 0.2.31
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/README.md +12 -173
- data/lib/dead_bro/subscriber.rb +33 -0
- 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: b6c0f13b23ff342d0ea4365872e2f380a949a8aaf3fd69d98606336854d14c9c
|
|
4
|
+
data.tar.gz: a9b8a2fae51c26e7cd9b2f1d676c6742a5a5b4829f0c182417af7eabdf2581c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e70b0d0b091dfacf1db61ea287a47bb1944153968bc3f225c943baf6a195c099dfd88199e59a942230284f3cfc94dcbf207d942e03630ac14850f818c1dc0928
|
|
7
|
+
data.tar.gz: 1e5f8605da3bf8c418d4c16025be5a24b7f89af1ca47d7bb6c767f790205c498e3023543b739b1568156547c21b8cfaf2bf327c573d8177aad88049e395352f2
|
data/README.md
CHANGED
|
@@ -65,115 +65,9 @@ Use the DeadBro UI to turn features on or off, set sample rates, define controll
|
|
|
65
65
|
|
|
66
66
|
You can still set `config.enabled` in Ruby if you need to force the integration off in a given environment before any remote settings arrive; otherwise the dashboard can control `enabled` like other remote settings.
|
|
67
67
|
|
|
68
|
-
##
|
|
68
|
+
## Request Sampling, Exclusions & Whitelisting
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
## Request Sampling
|
|
73
|
-
|
|
74
|
-
DeadBro supports configurable request sampling to reduce the volume of metrics sent to your APM endpoint, which is useful for high-traffic applications. Prefer setting this in the DeadBro app; use Ruby if you need a local override.
|
|
75
|
-
|
|
76
|
-
### Configuration
|
|
77
|
-
|
|
78
|
-
Set the sample rate as a percentage (1-100):
|
|
79
|
-
|
|
80
|
-
```ruby
|
|
81
|
-
# Track 50% of requests
|
|
82
|
-
DeadBro.configure do |config|
|
|
83
|
-
config.sample_rate = 50
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Track 10% of requests (useful for high-traffic apps)
|
|
87
|
-
DeadBro.configure do |config|
|
|
88
|
-
config.sample_rate = 10
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Track all requests (default)
|
|
92
|
-
DeadBro.configure do |config|
|
|
93
|
-
config.sample_rate = 100
|
|
94
|
-
end
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### How It Works
|
|
98
|
-
|
|
99
|
-
- **Random Sampling**: Each request has a random chance of being tracked based on the sample rate
|
|
100
|
-
- **Consistent Per-Request**: The sampling decision is made once per request and applies to all metrics for that request
|
|
101
|
-
- **Debug Logging**: Skipped requests do not count towards the montly limit
|
|
102
|
-
- **Error Tracking**: Errors are still tracked regardless of sampling
|
|
103
|
-
|
|
104
|
-
### Use Cases
|
|
105
|
-
|
|
106
|
-
- **High-Traffic Applications**: Reduce APM data volume and costs
|
|
107
|
-
- **Development/Staging**: Sample fewer requests to reduce noise
|
|
108
|
-
- **Performance Testing**: Track a subset of requests during load testing
|
|
109
|
-
- **Cost Optimization**: Balance monitoring coverage with data costs
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
## Excluding Controllers and Jobs
|
|
113
|
-
|
|
114
|
-
You can exclude specific controllers and jobs from APM tracking (dashboard first; Ruby optional).
|
|
115
|
-
|
|
116
|
-
### Configuration
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
```ruby
|
|
120
|
-
DeadBro.configure do |config|
|
|
121
|
-
# Controller-only or controller#action patterns in one list (wildcards supported)
|
|
122
|
-
config.excluded_controllers = [
|
|
123
|
-
"HealthChecksController",
|
|
124
|
-
"Admin::*",
|
|
125
|
-
"UsersController#show",
|
|
126
|
-
"Admin::ReportsController#index",
|
|
127
|
-
"Admin::*#*"
|
|
128
|
-
]
|
|
129
|
-
|
|
130
|
-
config.excluded_jobs = [
|
|
131
|
-
"ActiveStorage::AnalyzeJob",
|
|
132
|
-
"Admin::*"
|
|
133
|
-
]
|
|
134
|
-
end
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Notes:
|
|
138
|
-
- Wildcards `*` are supported (e.g., `Admin::*`, `Admin::*#*`).
|
|
139
|
-
- Matching uses full names like `UsersController`, `Admin::ReportsController#index`, `MyJob`.
|
|
140
|
-
|
|
141
|
-
## Exclusive Tracking (Whitelist Mode)
|
|
142
|
-
|
|
143
|
-
You can configure DeadBro to **only** track specific controllers, actions, or jobs. Prefer the dashboard; use Ruby for overrides.
|
|
144
|
-
|
|
145
|
-
### Configuration
|
|
146
|
-
|
|
147
|
-
```ruby
|
|
148
|
-
DeadBro.configure do |config|
|
|
149
|
-
# Only track these controllers/actions (patterns can include #action or wildcards)
|
|
150
|
-
config.exclusive_controllers = [
|
|
151
|
-
"UsersController#show",
|
|
152
|
-
"UsersController#index",
|
|
153
|
-
"Admin::ReportsController#*",
|
|
154
|
-
"Api::*#*"
|
|
155
|
-
]
|
|
156
|
-
|
|
157
|
-
config.exclusive_jobs = [
|
|
158
|
-
"PaymentProcessingJob",
|
|
159
|
-
"EmailDeliveryJob",
|
|
160
|
-
"Admin::*"
|
|
161
|
-
]
|
|
162
|
-
end
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### How It Works
|
|
166
|
-
|
|
167
|
-
- **If `exclusive_controllers` or `exclusive_jobs` is empty/not defined**: All controllers/actions/jobs are tracked (default behavior)
|
|
168
|
-
- **If `exclusive_controllers` or `exclusive_jobs` is defined with values**: Only matching controllers/actions/jobs are tracked
|
|
169
|
-
- **Exclusion takes precedence**: If something matches both `excluded_*` and `exclusive_*`, it is excluded (exclusion is checked first)
|
|
170
|
-
|
|
171
|
-
### Use Cases
|
|
172
|
-
|
|
173
|
-
- **Focus on Critical Paths**: Monitor only your most important endpoints
|
|
174
|
-
- **Cost Optimization**: Track only specific high-value operations
|
|
175
|
-
- **Debugging**: Temporarily focus on specific controllers/jobs during investigation
|
|
176
|
-
- **Compliance**: Track only operations that require monitoring for compliance reasons
|
|
70
|
+
To control data volume, DeadBro supports request sampling (track a percentage of requests), excluding specific controllers/jobs from tracking, and whitelisting (tracking *only* specific controllers/jobs). All of this is configured in the DeadBro dashboard — sample rate, `excluded_controllers`/`excluded_jobs`, and `exclusive_controllers`/`exclusive_jobs` patterns (wildcards like `Admin::*` and `Admin::*#*` supported). Exclusion always takes precedence over whitelisting when a pattern matches both.
|
|
177
71
|
|
|
178
72
|
## SQL Query Tracking
|
|
179
73
|
|
|
@@ -198,43 +92,19 @@ DeadBro can automatically capture the query plan (`EXPLAIN`) of slow SELECT quer
|
|
|
198
92
|
- **Value scrubbing**: quoted string literals echoed in plan text (e.g. `Filter: email = 'a@b.com'`) are replaced with `?` before the plan leaves your app.
|
|
199
93
|
- **Bounded overhead**: plans are captured on background threads (max 3 concurrent per request); at request end DeadBro waits at most 0.5s for stragglers, then drops them.
|
|
200
94
|
|
|
201
|
-
### How It Works
|
|
202
|
-
|
|
203
|
-
- **Automatic Detection**: when a SELECT exceeds `slow_query_threshold_ms`, DeadBro captures its plan in the background
|
|
204
|
-
- **Database Support**: PostgreSQL, MySQL, SQLite (`EXPLAIN QUERY PLAN`), and any adapter with a standard `EXPLAIN`
|
|
205
|
-
|
|
206
95
|
### Configuration
|
|
207
96
|
|
|
208
|
-
- **`explain_analyze_enabled`** (default: `false`)
|
|
209
|
-
- **`slow_query_threshold_ms`** (default: `500`) - queries taking longer than this threshold will have their execution plan captured
|
|
97
|
+
- **`explain_analyze_enabled`** (default: `false`) — this is the one setting that must be turned on in Ruby; the dashboard toggle can only turn capture *off*, never on, as an extra safety rail:
|
|
210
98
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
config.explain_analyze_enabled = true
|
|
217
|
-
config.slow_query_threshold_ms = 500
|
|
218
|
-
|
|
219
|
-
# Or use a higher threshold for production
|
|
220
|
-
# config.slow_query_threshold_ms = 1000 # Only explain queries > 1 second
|
|
221
|
-
end
|
|
222
|
-
```
|
|
99
|
+
```ruby
|
|
100
|
+
DeadBro.configure do |config|
|
|
101
|
+
config.explain_analyze_enabled = true
|
|
102
|
+
end
|
|
103
|
+
```
|
|
223
104
|
|
|
224
|
-
|
|
105
|
+
- Everything else — the `slow_query_threshold_ms` cutoff and enabling/disabling the feature — is managed from the dashboard.
|
|
225
106
|
|
|
226
|
-
When a slow query is detected, the `explain_plan` field in the SQL query data
|
|
227
|
-
- **PostgreSQL / MySQL**: `EXPLAIN` output — the planner's chosen strategy, estimated costs and row counts
|
|
228
|
-
- **SQLite**: `EXPLAIN QUERY PLAN` output
|
|
229
|
-
- **Other databases**: standard `EXPLAIN` output
|
|
230
|
-
|
|
231
|
-
This execution plan helps you:
|
|
232
|
-
- Identify missing indexes
|
|
233
|
-
- Understand query execution order
|
|
234
|
-
- Spot full table scans
|
|
235
|
-
- Optimize JOIN operations
|
|
236
|
-
|
|
237
|
-
Because the statement is not executed, plans show the planner's *estimates* rather than actual runtimes — usually exactly what you need to spot a missing index or an unexpected sequential scan.
|
|
107
|
+
When a slow query is detected, the `explain_plan` field in the SQL query data contains the database's `EXPLAIN` (or `EXPLAIN QUERY PLAN` on SQLite) output — the planner's chosen strategy, estimated costs and row counts — useful for spotting missing indexes or unexpected sequential scans. Because the statement is never executed, plans show estimates rather than actual runtimes.
|
|
238
108
|
|
|
239
109
|
## View Rendering Tracking
|
|
240
110
|
|
|
@@ -259,20 +129,7 @@ By default, DeadBro uses **lightweight memory tracking** that has minimal perfor
|
|
|
259
129
|
- **GC Efficiency Analysis**: Monitor garbage collection effectiveness
|
|
260
130
|
- **Zero Allocation Tracking**: No object allocation tracking by default (can be enabled)
|
|
261
131
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
Usually managed in the dashboard; Ruby example:
|
|
265
|
-
|
|
266
|
-
```ruby
|
|
267
|
-
DeadBro.configure do |config|
|
|
268
|
-
config.memory_tracking_enabled = true # Enable lightweight memory tracking (default: true)
|
|
269
|
-
config.allocation_tracking_enabled = false # Enable detailed allocation tracking (default: false)
|
|
270
|
-
config.allocation_sample_rate = 100 # % of requests that pay for allocation tracking when enabled (1-100, default: 100)
|
|
271
|
-
|
|
272
|
-
# Sampling configuration
|
|
273
|
-
config.sample_rate = 100 # Percentage of requests to track (1-100, default: 100)
|
|
274
|
-
end
|
|
275
|
-
```
|
|
132
|
+
`memory_tracking_enabled`, `allocation_tracking_enabled`, and `allocation_sample_rate` are all managed from the dashboard.
|
|
276
133
|
|
|
277
134
|
**Performance Impact:**
|
|
278
135
|
- **Lightweight mode** (`memory_tracking_enabled`, ~0.1ms overhead per request): RSS before/after, GC pressure, the retained-vs-transient signals (`heap_live_slots_growth`, `malloc_increase_bytes`), and per-phase allocation attribution (`allocation_phases` — which of `sql`/`view`/`elasticsearch` allocated the request's objects).
|
|
@@ -310,25 +167,7 @@ Everything is **best effort** and designed to be **safe and low overhead**:
|
|
|
310
167
|
|
|
311
168
|
### Configuration
|
|
312
169
|
|
|
313
|
-
Enable or disable
|
|
314
|
-
|
|
315
|
-
```ruby
|
|
316
|
-
DeadBro.configure do |config|
|
|
317
|
-
# Enable the periodic job queue monitor (disabled by default)
|
|
318
|
-
config.job_queue_monitoring_enabled = true
|
|
319
|
-
|
|
320
|
-
# Enable best-effort collectors (all default to false)
|
|
321
|
-
config.enable_db_stats = true # ActiveRecord pool + ping latency
|
|
322
|
-
config.enable_process_stats = true # pid, hostname, RSS, GC, threads, fds
|
|
323
|
-
config.enable_system_stats = true # CPU%, memory, disk, network
|
|
324
|
-
|
|
325
|
-
# Filesystem paths to report disk usage for (default: ["/"])
|
|
326
|
-
config.disk_paths = ["/", "/var"]
|
|
327
|
-
|
|
328
|
-
# Network interfaces to ignore when computing rx/tx stats
|
|
329
|
-
config.interfaces_ignore = %w[lo docker0]
|
|
330
|
-
end
|
|
331
|
-
```
|
|
170
|
+
Enable or disable the job queue monitor and the individual collectors (`enable_db_stats`, `enable_process_stats`, `enable_system_stats`), plus `disk_paths` and `interfaces_ignore`, from the DeadBro dashboard.
|
|
332
171
|
|
|
333
172
|
### Example Payload Shape
|
|
334
173
|
|
data/lib/dead_bro/subscriber.rb
CHANGED
|
@@ -164,6 +164,7 @@ module DeadBro
|
|
|
164
164
|
duration_ms: duration_ms,
|
|
165
165
|
rails_env: DeadBro.env,
|
|
166
166
|
host: DeadBro.safe_hostname,
|
|
167
|
+
request_host: safe_request_host(data),
|
|
167
168
|
process_kind: DeadBro.process_kind,
|
|
168
169
|
params: safe_params(data),
|
|
169
170
|
user_agent: safe_user_agent(data),
|
|
@@ -197,6 +198,7 @@ module DeadBro
|
|
|
197
198
|
view_runtime_ms: data[:view_runtime],
|
|
198
199
|
db_runtime_ms: data[:db_runtime],
|
|
199
200
|
host: DeadBro.safe_hostname,
|
|
201
|
+
request_host: safe_request_host(data),
|
|
200
202
|
rails_env: DeadBro.env,
|
|
201
203
|
process_kind: DeadBro.process_kind,
|
|
202
204
|
params: safe_params(data),
|
|
@@ -330,6 +332,37 @@ module DeadBro
|
|
|
330
332
|
end
|
|
331
333
|
end
|
|
332
334
|
|
|
335
|
+
# The domain the request was served on (request.host) — distinct from `host`,
|
|
336
|
+
# which is the machine's OS hostname. Lets one app that answers on several
|
|
337
|
+
# domains be sliced by domain in the dashboard. Port and userinfo are dropped;
|
|
338
|
+
# value is lowercased so "Example.com" and "example.com" aren't two rows.
|
|
339
|
+
def self.safe_request_host(data)
|
|
340
|
+
raw =
|
|
341
|
+
if data[:request] && data[:request].respond_to?(:host)
|
|
342
|
+
data[:request].host
|
|
343
|
+
elsif data[:headers]
|
|
344
|
+
headers = data[:headers]
|
|
345
|
+
if headers.respond_to?(:[])
|
|
346
|
+
headers["HTTP_HOST"] || headers["Host"] || headers["host"]
|
|
347
|
+
elsif headers.respond_to?(:env)
|
|
348
|
+
headers.env && headers.env["HTTP_HOST"]
|
|
349
|
+
end
|
|
350
|
+
elsif data[:env].is_a?(Hash)
|
|
351
|
+
data[:env]["HTTP_HOST"]
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
host = sanitize_string(raw)
|
|
355
|
+
return "" if host.empty?
|
|
356
|
+
|
|
357
|
+
# Strip any userinfo@ and a trailing :port so only the hostname remains.
|
|
358
|
+
# Only a numeric trailing port is removed, so IPv6 literals ([::1]) survive.
|
|
359
|
+
host = host.split("@").last.to_s
|
|
360
|
+
host = host.sub(/:\d+\z/, "")
|
|
361
|
+
host.downcase[0, 255]
|
|
362
|
+
rescue
|
|
363
|
+
""
|
|
364
|
+
end
|
|
365
|
+
|
|
333
366
|
def self.safe_user_agent(data)
|
|
334
367
|
begin
|
|
335
368
|
# Prefer request object if available
|
data/lib/dead_bro/version.rb
CHANGED