Class: DeadBro::Configuration
- Inherits:
-
Object
- Object
- DeadBro::Configuration
- Defined in:
- lib/dead_bro/configuration.rb
Constant Summary collapse
- HEARTBEAT_INTERVAL =
seconds
60- METRICS_BACKEND_SKIP_AFTER_507_SECONDS =
10 minutes
600- DEPLOY_REVISION_ENV_KEYS =
First non-empty ENV value wins for release/revision payloads and deploy grouping on the server. Order is roughly: DeadBro-native → common CI/hosting → observability tooling.
%w[ DEAD_BRO_DEPLOY_ID dead_bro_DEPLOY_ID GIT_REV GIT_COMMIT GIT_COMMIT_SHA GIT_SHA CODEBUILD_RESOLVED_SOURCE_REVISION HEROKU_SLUG_COMMIT RENDER_GIT_COMMIT DD_VERSION APP_REVISION RELEASE_VERSION SOURCE_VERSION ].freeze
- REMOTE_SETTING_KEYS =
%w[ enabled sample_rate memory_tracking_enabled allocation_tracking_enabled explain_analyze_enabled slow_query_threshold_ms max_sql_queries_to_send max_logs_to_send excluded_controllers excluded_jobs exclusive_controllers exclusive_jobs job_queue_monitoring_enabled enable_db_stats enable_process_stats enable_system_stats ].freeze
Instance Attribute Summary collapse
-
#allocation_tracking_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#api_key ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#circuit_breaker_enabled ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#circuit_breaker_failure_threshold ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#circuit_breaker_recovery_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#circuit_breaker_retry_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#disk_paths ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#enable_db_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#enable_process_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#enable_system_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#enabled ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#excluded_controllers ⇒ Object
Readers for exclusion lists.
-
#excluded_jobs ⇒ Object
Readers for exclusion lists.
-
#exclusive_controllers ⇒ Object
Readers for exclusion lists.
-
#exclusive_jobs ⇒ Object
Readers for exclusion lists.
-
#explain_analyze_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#interfaces_ignore ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#job_queue_monitoring_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#last_heartbeat_at ⇒ Object
Last successful heartbeat HTTP response time while disabled (in-memory only).
-
#last_heartbeat_attempt_at ⇒ Object
Throttles heartbeat attempts to HEARTBEAT_INTERVAL (set when a heartbeat request is started).
-
#max_logs_to_send ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#max_sql_queries_to_send ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#memory_tracking_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#open_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#read_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#ruby_dev ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads).
-
#sample_rate ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
-
#settings_received_at ⇒ Object
Tracks when we last received settings from the backend (in-memory only).
-
#skip_until ⇒ Object
After HTTP 507 Insufficient Storage from the API, skip all tracking until this UTC time (in-memory only).
-
#slow_query_threshold_ms ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses).
Instance Method Summary collapse
-
#apply_remote_settings(hash) ⇒ Object
Apply a settings hash received from the backend response.
-
#deploy_id ⇒ Object
Current release revision sent as ‘revision` on all API payloads — same semantics as `#resolve_deploy_id`.
-
#deploy_id=(value) ⇒ Object
Overrides ENV-based resolution when set to a non-empty string (or clears override when nil/blank).
- #excluded_controller?(controller_name, action_name = nil) ⇒ Boolean
- #excluded_job?(job_class_name) ⇒ Boolean
- #exclusive_controller?(controller_name, action_name) ⇒ Boolean
- #exclusive_job?(job_class_name) ⇒ Boolean
- #heartbeat_due? ⇒ Boolean
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
- #resolve_api_key ⇒ Object
- #resolve_deploy_id ⇒ Object
-
#resolve_sample_rate ⇒ Object
Returns the configured sample_rate only (no ENV fallback).
- #should_sample? ⇒ Boolean
- #skip_tracking? ⇒ Boolean
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/dead_bro/configuration.rb', line 64 def initialize @api_key = nil @open_timeout = 1.0 @read_timeout = 1.0 @enabled = true @ruby_dev = false @circuit_breaker_enabled = true @circuit_breaker_failure_threshold = 3 @circuit_breaker_recovery_timeout = 60 @circuit_breaker_retry_timeout = 300 @explicit_deploy_revision = nil @disk_paths = ["/"] @interfaces_ignore = %w[lo lo0 docker0] # Remote-managed defaults (used until backend sends real values) @sample_rate = 100 @memory_tracking_enabled = true @allocation_tracking_enabled = false @explain_analyze_enabled = false @slow_query_threshold_ms = 500 @max_sql_queries_to_send = 500 @max_logs_to_send = 100 self.excluded_controllers = [] self.excluded_jobs = [] self.exclusive_controllers = [] self.exclusive_jobs = [] @job_queue_monitoring_enabled = false @enable_db_stats = false @enable_process_stats = false @enable_system_stats = false @settings_received_at = nil @skip_until = nil @last_heartbeat_at = nil @last_heartbeat_attempt_at = nil @settings_mutex = Mutex.new end |
Instance Attribute Details
#allocation_tracking_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def allocation_tracking_enabled @allocation_tracking_enabled end |
#api_key ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def api_key @api_key end |
#circuit_breaker_enabled ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def circuit_breaker_enabled @circuit_breaker_enabled end |
#circuit_breaker_failure_threshold ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def circuit_breaker_failure_threshold @circuit_breaker_failure_threshold end |
#circuit_breaker_recovery_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def circuit_breaker_recovery_timeout @circuit_breaker_recovery_timeout end |
#circuit_breaker_retry_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def circuit_breaker_retry_timeout @circuit_breaker_retry_timeout end |
#disk_paths ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def disk_paths @disk_paths end |
#enable_db_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def enable_db_stats @enable_db_stats end |
#enable_process_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def enable_process_stats @enable_process_stats end |
#enable_system_stats ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def enable_system_stats @enable_system_stats end |
#enabled ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def enabled @enabled end |
#excluded_controllers ⇒ Object
Readers for exclusion lists. Writers are defined below so we can compile and cache the regex form once, instead of rebuilding it per request.
20 21 22 |
# File 'lib/dead_bro/configuration.rb', line 20 def excluded_controllers @excluded_controllers end |
#excluded_jobs ⇒ Object
Readers for exclusion lists. Writers are defined below so we can compile and cache the regex form once, instead of rebuilding it per request.
20 21 22 |
# File 'lib/dead_bro/configuration.rb', line 20 def excluded_jobs @excluded_jobs end |
#exclusive_controllers ⇒ Object
Readers for exclusion lists. Writers are defined below so we can compile and cache the regex form once, instead of rebuilding it per request.
20 21 22 |
# File 'lib/dead_bro/configuration.rb', line 20 def exclusive_controllers @exclusive_controllers end |
#exclusive_jobs ⇒ Object
Readers for exclusion lists. Writers are defined below so we can compile and cache the regex form once, instead of rebuilding it per request.
20 21 22 |
# File 'lib/dead_bro/configuration.rb', line 20 def exclusive_jobs @exclusive_jobs end |
#explain_analyze_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def explain_analyze_enabled @explain_analyze_enabled end |
#interfaces_ignore ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def interfaces_ignore @interfaces_ignore end |
#job_queue_monitoring_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def job_queue_monitoring_enabled @job_queue_monitoring_enabled end |
#last_heartbeat_at ⇒ Object
Last successful heartbeat HTTP response time while disabled (in-memory only)
30 31 32 |
# File 'lib/dead_bro/configuration.rb', line 30 def last_heartbeat_at @last_heartbeat_at end |
#last_heartbeat_attempt_at ⇒ Object
Throttles heartbeat attempts to HEARTBEAT_INTERVAL (set when a heartbeat request is started)
33 34 35 |
# File 'lib/dead_bro/configuration.rb', line 33 def last_heartbeat_attempt_at @last_heartbeat_attempt_at end |
#max_logs_to_send ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def max_logs_to_send @max_logs_to_send end |
#max_sql_queries_to_send ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def max_sql_queries_to_send @max_sql_queries_to_send end |
#memory_tracking_enabled ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def memory_tracking_enabled @memory_tracking_enabled end |
#open_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def open_timeout @open_timeout end |
#read_timeout ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def read_timeout @read_timeout end |
#ruby_dev ⇒ Object
Local-only settings (not overwritten by API ‘settings` payloads). Note: `enabled` may still be updated remotely via apply_remote_settings when the backend returns it in a response; local configure() values apply until the next remote update.
8 9 10 |
# File 'lib/dead_bro/configuration.rb', line 8 def ruby_dev @ruby_dev end |
#sample_rate ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def sample_rate @sample_rate end |
#settings_received_at ⇒ Object
Tracks when we last received settings from the backend (in-memory only)
23 24 25 |
# File 'lib/dead_bro/configuration.rb', line 23 def settings_received_at @settings_received_at end |
#skip_until ⇒ Object
After HTTP 507 Insufficient Storage from the API, skip all tracking until this UTC time (in-memory only). Cleared on the next successful API response.
27 28 29 |
# File 'lib/dead_bro/configuration.rb', line 27 def skip_until @skip_until end |
#slow_query_threshold_ms ⇒ Object
Remote-managed settings (overwritten by backend JSON ‘settings` on successful API responses)
13 14 15 |
# File 'lib/dead_bro/configuration.rb', line 13 def slow_query_threshold_ms @slow_query_threshold_ms end |
Instance Method Details
#apply_remote_settings(hash) ⇒ Object
Apply a settings hash received from the backend response. Only known keys are applied; unknown keys are silently ignored. Serialized so concurrent HTTP threads do not interleave writes with request-thread reads.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/dead_bro/configuration.rb', line 136 def apply_remote_settings(hash) return unless hash.is_a?(Hash) @settings_mutex.synchronize do hash.each do |key, value| k = key.to_s next unless REMOTE_SETTING_KEYS.include?(k) case k when "sample_rate", "slow_query_threshold_ms", "max_sql_queries_to_send", "max_logs_to_send" send(:"#{k}=", value.to_i) when "enabled", "memory_tracking_enabled", "allocation_tracking_enabled", "explain_analyze_enabled", "job_queue_monitoring_enabled", "enable_db_stats", "enable_process_stats", "enable_system_stats" send(:"#{k}=", !!value) when "excluded_controllers", "excluded_jobs", "exclusive_controllers", "exclusive_jobs" send(:"#{k}=", Array(value).map(&:to_s)) end end end end |
#deploy_id ⇒ Object
Current release revision sent as ‘revision` on all API payloads — same semantics as `#resolve_deploy_id`.
103 104 105 |
# File 'lib/dead_bro/configuration.rb', line 103 def deploy_id resolve_deploy_id end |
#deploy_id=(value) ⇒ Object
Overrides ENV-based resolution when set to a non-empty string (or clears override when nil/blank).
108 109 110 111 |
# File 'lib/dead_bro/configuration.rb', line 108 def deploy_id=(value) s = value&.respond_to?(:to_s) ? value.to_s.strip : "" @explicit_deploy_revision = s.empty? ? nil : s end |
#excluded_controller?(controller_name, action_name = nil) ⇒ Boolean
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/dead_bro/configuration.rb', line 186 def excluded_controller?(controller_name, action_name = nil) compiled = @compiled_excluded_controllers return false if compiled.nil? || compiled.empty? if action_name target = "#{controller_name}##{action_name}" compiled.each do |entry| if entry[:has_hash] return true if match_compiled?(target, entry) elsif match_compiled?(controller_name, entry) return true end end return false end compiled.each do |entry| next if entry[:has_hash] return true if match_compiled?(controller_name, entry) end false end |
#excluded_job?(job_class_name) ⇒ Boolean
209 210 211 212 213 |
# File 'lib/dead_bro/configuration.rb', line 209 def excluded_job?(job_class_name) compiled = @compiled_excluded_jobs return false if compiled.nil? || compiled.empty? compiled.any? { |entry| match_compiled?(job_class_name, entry) } end |
#exclusive_controller?(controller_name, action_name) ⇒ Boolean
221 222 223 224 225 226 |
# File 'lib/dead_bro/configuration.rb', line 221 def exclusive_controller?(controller_name, action_name) compiled = @compiled_exclusive_controllers return true if compiled.nil? || compiled.empty? target = "#{controller_name}##{action_name}" compiled.any? { |entry| match_compiled?(target, entry) } end |
#exclusive_job?(job_class_name) ⇒ Boolean
215 216 217 218 219 |
# File 'lib/dead_bro/configuration.rb', line 215 def exclusive_job?(job_class_name) compiled = @compiled_exclusive_jobs return true if compiled.nil? || compiled.empty? compiled.any? { |entry| match_compiled?(job_class_name, entry) } end |
#heartbeat_due? ⇒ Boolean
157 158 159 160 |
# File 'lib/dead_bro/configuration.rb', line 157 def heartbeat_due? return false if api_key.nil? last_heartbeat_attempt_at.nil? || (Time.now.utc - last_heartbeat_attempt_at) >= HEARTBEAT_INTERVAL end |
#resolve_api_key ⇒ Object
244 245 246 247 248 |
# File 'lib/dead_bro/configuration.rb', line 244 def resolve_api_key return @api_key unless @api_key.nil? ENV["DEAD_BRO_API_KEY"] end |
#resolve_deploy_id ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/dead_bro/configuration.rb', line 169 def resolve_deploy_id explicit = @explicit_deploy_revision&.to_s&.strip return explicit unless explicit.nil? || explicit.empty? DEPLOY_REVISION_ENV_KEYS.each do |key| v = ENV[key] next unless v.respond_to?(:to_s) stripped = v.to_s.strip next if stripped.empty? return stripped end DeadBro.process_deploy_id end |
#resolve_sample_rate ⇒ Object
Returns the configured sample_rate only (no ENV fallback). Use DeadBro.configure or remote settings.
240 241 242 |
# File 'lib/dead_bro/configuration.rb', line 240 def resolve_sample_rate @sample_rate end |
#should_sample? ⇒ Boolean
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/dead_bro/configuration.rb', line 228 def should_sample? sample_rate = resolve_sample_rate sample_rate = 100 if sample_rate.nil? return true if sample_rate >= 100 return false if sample_rate <= 0 # Generate random number 1-100 and check if it's within sample rate rand(1..100) <= sample_rate end |
#skip_tracking? ⇒ Boolean
162 163 164 165 166 167 |
# File 'lib/dead_bro/configuration.rb', line 162 def skip_tracking? t = skip_until return false unless t Time.now.utc < t end |