apm_bro 0.1.14 → 0.1.15

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.
@@ -5,12 +5,12 @@ require "active_support/notifications"
5
5
  module ApmBro
6
6
  class MemoryTrackingSubscriber
7
7
  # Object allocation events
8
- ALLOCATION_EVENT = "object_allocations.active_support".freeze
9
-
8
+ ALLOCATION_EVENT = "object_allocations.active_support"
9
+
10
10
  THREAD_LOCAL_KEY = :apm_bro_memory_events
11
11
  # Consider objects larger than this many bytes as "large"
12
12
  LARGE_OBJECT_THRESHOLD = 1_000_000 # 1MB threshold for large objects
13
-
13
+
14
14
  # Performance optimization settings
15
15
  ALLOCATION_SAMPLING_RATE = 1 # Track all when enabled (adjust in production)
16
16
  MAX_ALLOCATIONS_PER_REQUEST = 1000 # Limit allocations tracked per request
@@ -28,18 +28,18 @@ module ApmBro
28
28
  next unless rand < ALLOCATION_SAMPLING_RATE
29
29
  track_allocation(data, started, finished)
30
30
  end
31
- rescue StandardError
31
+ rescue
32
32
  # Allocation tracking might not be available in all Ruby versions
33
33
  end
34
34
  end
35
- rescue StandardError
35
+ rescue
36
36
  # Never raise from instrumentation install
37
37
  end
38
38
 
39
39
  def self.start_request_tracking
40
40
  # Only track if memory tracking is enabled
41
41
  return unless ApmBro.configuration.memory_tracking_enabled
42
-
42
+
43
43
  Thread.current[THREAD_LOCAL_KEY] = {
44
44
  allocations: [],
45
45
  memory_snapshots: [],
@@ -54,7 +54,7 @@ module ApmBro
54
54
  def self.stop_request_tracking
55
55
  events = Thread.current[THREAD_LOCAL_KEY]
56
56
  Thread.current[THREAD_LOCAL_KEY] = nil
57
-
57
+
58
58
  if events
59
59
  events[:gc_after] = gc_stats
60
60
  events[:memory_after] = memory_usage_mb
@@ -67,20 +67,20 @@ module ApmBro
67
67
  events[:large_objects] = sample_large_objects
68
68
  end
69
69
  end
70
-
70
+
71
71
  events || {}
72
72
  end
73
73
 
74
74
  def self.track_allocation(data, started, finished)
75
75
  return unless Thread.current[THREAD_LOCAL_KEY]
76
-
76
+
77
77
  # Only track if we have meaningful allocation data
78
78
  return unless data.is_a?(Hash) && data[:count] && data[:size]
79
-
79
+
80
80
  # Limit allocations per request to prevent memory bloat
81
81
  allocations = Thread.current[THREAD_LOCAL_KEY][:allocations]
82
82
  return if allocations.length >= MAX_ALLOCATIONS_PER_REQUEST
83
-
83
+
84
84
  # Simplified allocation tracking (avoid expensive operations)
85
85
  allocation = {
86
86
  class_name: data[:class_name] || "Unknown",
@@ -88,7 +88,7 @@ module ApmBro
88
88
  size: data[:size]
89
89
  # Removed expensive fields: duration_ms, timestamp, memory_usage
90
90
  }
91
-
91
+
92
92
  # Track large object allocations (these are rare and important)
93
93
  if data[:size] > LARGE_OBJECT_THRESHOLD
94
94
  large_object = allocation.merge(
@@ -97,13 +97,13 @@ module ApmBro
97
97
  )
98
98
  Thread.current[THREAD_LOCAL_KEY][:large_objects] << large_object
99
99
  end
100
-
100
+
101
101
  Thread.current[THREAD_LOCAL_KEY][:allocations] << allocation
102
102
  end
103
103
 
104
104
  def self.take_memory_snapshot(label = nil)
105
105
  return unless Thread.current[THREAD_LOCAL_KEY]
106
-
106
+
107
107
  snapshot = {
108
108
  label: label || "snapshot_#{Time.now.to_i}",
109
109
  memory_usage: memory_usage_mb,
@@ -112,45 +112,45 @@ module ApmBro
112
112
  object_count: object_count,
113
113
  heap_pages: heap_pages
114
114
  }
115
-
115
+
116
116
  Thread.current[THREAD_LOCAL_KEY][:memory_snapshots] << snapshot
117
117
  end
118
118
 
119
119
  def self.analyze_memory_performance(memory_events)
120
120
  return {} if memory_events.empty?
121
-
121
+
122
122
  allocations = memory_events[:allocations] || []
123
123
  large_objects = memory_events[:large_objects] || []
124
124
  snapshots = memory_events[:memory_snapshots] || []
125
-
125
+
126
126
  # Calculate memory growth
127
127
  memory_growth = 0
128
128
  if memory_events[:memory_before] && memory_events[:memory_after]
129
129
  memory_growth = memory_events[:memory_after] - memory_events[:memory_before]
130
130
  end
131
-
131
+
132
132
  # Calculate allocation totals
133
133
  total_allocations = allocations.sum { |a| a[:count] }
134
134
  total_allocated_size = allocations.sum { |a| a[:size] }
135
-
135
+
136
136
  # Group allocations by class
137
137
  allocations_by_class = allocations.group_by { |a| a[:class_name] }
138
- .transform_values { |allocs|
139
- {
140
- count: allocs.sum { |a| a[:count] },
141
- size: allocs.sum { |a| a[:size] }
142
- }
143
- }
144
-
138
+ .transform_values { |allocs|
139
+ {
140
+ count: allocs.sum { |a| a[:count] },
141
+ size: allocs.sum { |a| a[:size] }
142
+ }
143
+ }
144
+
145
145
  # Find top allocating classes
146
146
  top_allocating_classes = allocations_by_class.sort_by { |_, data| -data[:size] }.first(10)
147
-
147
+
148
148
  # Analyze large objects
149
149
  large_object_analysis = analyze_large_objects(large_objects)
150
-
150
+
151
151
  # Analyze memory snapshots for trends
152
152
  memory_trends = analyze_memory_trends(snapshots)
153
-
153
+
154
154
  # Calculate GC efficiency
155
155
  gc_efficiency = calculate_gc_efficiency(memory_events[:gc_before], memory_events[:gc_after])
156
156
 
@@ -164,13 +164,13 @@ module ApmBro
164
164
  object_type_deltas[k] = (after[k] || 0) - (before[k] || 0)
165
165
  end
166
166
  end
167
-
167
+
168
168
  {
169
169
  memory_growth_mb: memory_growth.round(2),
170
170
  total_allocations: total_allocations,
171
171
  total_allocated_size: total_allocated_size,
172
172
  total_allocated_size_mb: (total_allocated_size / 1_000_000.0).round(2),
173
- allocations_per_second: memory_events[:duration_seconds] > 0 ?
173
+ allocations_per_second: (memory_events[:duration_seconds] > 0) ?
174
174
  (total_allocations.to_f / memory_events[:duration_seconds]).round(2) : 0,
175
175
  top_allocating_classes: top_allocating_classes.map { |class_name, data|
176
176
  {
@@ -190,13 +190,13 @@ module ApmBro
190
190
 
191
191
  def self.analyze_large_objects(large_objects)
192
192
  return {} if large_objects.empty?
193
-
193
+
194
194
  {
195
195
  count: large_objects.count,
196
196
  total_size_mb: large_objects.sum { |obj| obj[:size_mb] }.round(2),
197
197
  largest_object_mb: large_objects.max_by { |obj| obj[:size_mb] }[:size_mb],
198
198
  by_class: large_objects.group_by { |obj| obj[:class_name] }
199
- .transform_values(&:count)
199
+ .transform_values(&:count)
200
200
  }
201
201
  end
202
202
 
@@ -219,15 +219,23 @@ module ApmBro
219
219
  # Randomly sample to control overhead
220
220
  next unless rand < LARGE_OBJECT_SAMPLE_RATE
221
221
 
222
- size = ObjectSpace.memsize_of(obj) rescue 0
222
+ size = begin
223
+ ObjectSpace.memsize_of(obj)
224
+ rescue
225
+ 0
226
+ end
223
227
  next unless size && size > LARGE_OBJECT_THRESHOLD
224
228
 
225
- klass = (obj.respond_to?(:class) && obj.class) ? obj.class.name : "Unknown" rescue "Unknown"
226
- results << { class_name: klass, size: size, size_mb: (size / 1_000_000.0).round(2) }
229
+ klass = begin
230
+ (obj.respond_to?(:class) && obj.class) ? obj.class.name : "Unknown"
231
+ rescue
232
+ "Unknown"
233
+ end
234
+ results << {class_name: klass, size: size, size_mb: (size / 1_000_000.0).round(2)}
227
235
 
228
236
  break if results.length >= MAX_LARGE_OBJECTS
229
237
  end
230
- rescue StandardError
238
+ rescue
231
239
  # Best-effort only
232
240
  end
233
241
 
@@ -241,24 +249,24 @@ module ApmBro
241
249
  else
242
250
  {}
243
251
  end
244
- rescue StandardError
252
+ rescue
245
253
  {}
246
254
  end
247
255
 
248
256
  def self.analyze_memory_trends(snapshots)
249
257
  return {} if snapshots.length < 2
250
-
258
+
251
259
  # Calculate memory growth rate between snapshots
252
260
  memory_values = snapshots.map { |s| s[:memory_usage] }
253
261
  memory_growth_rates = []
254
-
262
+
255
263
  (1...memory_values.length).each do |i|
256
- growth = memory_values[i] - memory_values[i-1]
257
- time_diff = snapshots[i][:timestamp] - snapshots[i-1][:timestamp]
258
- rate = time_diff > 0 ? growth / time_diff : 0
264
+ growth = memory_values[i] - memory_values[i - 1]
265
+ time_diff = snapshots[i][:timestamp] - snapshots[i - 1][:timestamp]
266
+ rate = (time_diff > 0) ? growth / time_diff : 0
259
267
  memory_growth_rates << rate
260
268
  end
261
-
269
+
262
270
  {
263
271
  average_growth_rate_mb_per_second: memory_growth_rates.sum / memory_growth_rates.length,
264
272
  max_growth_rate_mb_per_second: memory_growth_rates.max,
@@ -270,12 +278,12 @@ module ApmBro
270
278
 
271
279
  def self.calculate_gc_efficiency(gc_before, gc_after)
272
280
  return {} unless gc_before && gc_after
273
-
281
+
274
282
  {
275
283
  gc_count_increase: (gc_after[:count] || 0) - (gc_before[:count] || 0),
276
284
  heap_pages_increase: (gc_after[:heap_allocated_pages] || 0) - (gc_before[:heap_allocated_pages] || 0),
277
285
  objects_allocated: (gc_after[:total_allocated_objects] || 0) - (gc_before[:total_allocated_objects] || 0),
278
- gc_frequency: gc_after[:count] && gc_before[:count] ?
286
+ gc_frequency: (gc_after[:count] && gc_before[:count]) ?
279
287
  (gc_after[:count] - gc_before[:count]).to_f / [gc_after[:count], 1].max : 0
280
288
  }
281
289
  end
@@ -284,12 +292,12 @@ module ApmBro
284
292
  # Use cached memory calculation to avoid expensive system calls
285
293
  @memory_cache ||= {}
286
294
  cache_key = Process.pid
287
-
295
+
288
296
  # Cache memory usage for 1 second to avoid repeated system calls
289
297
  if @memory_cache[cache_key] && (Time.now - @memory_cache[cache_key][:timestamp]) < 1
290
298
  return @memory_cache[cache_key][:memory]
291
299
  end
292
-
300
+
293
301
  memory = if defined?(GC) && GC.respond_to?(:stat)
294
302
  # Use GC stats as a proxy for memory usage (much faster than ps)
295
303
  gc_stats = GC.stat
@@ -299,10 +307,10 @@ module ApmBro
299
307
  else
300
308
  0
301
309
  end
302
-
303
- @memory_cache[cache_key] = { memory: memory, timestamp: Time.now }
310
+
311
+ @memory_cache[cache_key] = {memory: memory, timestamp: Time.now}
304
312
  memory
305
- rescue StandardError
313
+ rescue
306
314
  0
307
315
  end
308
316
 
@@ -321,7 +329,7 @@ module ApmBro
321
329
  else
322
330
  {}
323
331
  end
324
- rescue StandardError
332
+ rescue
325
333
  {}
326
334
  end
327
335
 
@@ -331,7 +339,7 @@ module ApmBro
331
339
  else
332
340
  0
333
341
  end
334
- rescue StandardError
342
+ rescue
335
343
  0
336
344
  end
337
345
 
@@ -341,7 +349,7 @@ module ApmBro
341
349
  else
342
350
  0
343
351
  end
344
- rescue StandardError
352
+ rescue
345
353
  0
346
354
  end
347
355
 
@@ -1,13 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rails/railtie"
3
+ begin
4
+ require "rails/railtie"
5
+ rescue LoadError
6
+ # Rails not available, skip railtie definition
7
+ end
8
+
9
+ # Only define Railtie if Rails is available
10
+ if defined?(Rails) && defined?(Rails::Railtie)
11
+ module ApmBro
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.
4
16
 
5
- module ApmBro
6
- class Railtie < ::Rails::Railtie
7
- initializer "apm_bro.configure" do |_app|
8
- # Allow host app to set config in Rails config, credentials, or ENV.
9
- # If host app sets config.x.apm_bro, mirror into gem configuration.
10
- begin
11
17
  if Rails.application.config.x.respond_to?(:apm_bro)
12
18
  xcfg = Rails.application.config.x.apm_bro
13
19
  ApmBro.configure do |cfg|
@@ -15,22 +21,20 @@ module ApmBro
15
21
  cfg.enabled = xcfg.enabled if xcfg.respond_to?(:enabled)
16
22
  end
17
23
  end
18
- rescue StandardError
24
+ rescue
19
25
  end
20
- end
21
26
 
22
- initializer "apm_bro.subscribe" do |app|
23
- app.config.after_initialize do
24
- begin
27
+ initializer "apm_bro.subscribe" do |app|
28
+ app.config.after_initialize do
25
29
  ApmBro::Subscriber.subscribe!(client: ApmBro::Client.new)
26
30
  # Install outgoing HTTP instrumentation
27
31
  require "apm_bro/http_instrumentation"
28
32
  ApmBro::HttpInstrumentation.install!(client: ApmBro::Client.new)
29
-
33
+
30
34
  # Install SQL query tracking
31
35
  require "apm_bro/sql_subscriber"
32
36
  ApmBro::SqlSubscriber.subscribe!
33
-
37
+
34
38
  # Install Rails cache tracking
35
39
  require "apm_bro/cache_subscriber"
36
40
  ApmBro::CacheSubscriber.subscribe!
@@ -42,18 +46,18 @@ module ApmBro
42
46
  # Install view rendering tracking
43
47
  require "apm_bro/view_rendering_subscriber"
44
48
  ApmBro::ViewRenderingSubscriber.subscribe!(client: ApmBro::Client.new)
45
-
49
+
46
50
  # Install lightweight memory tracking (default)
47
51
  require "apm_bro/lightweight_memory_tracker"
48
52
  require "apm_bro/memory_leak_detector"
49
53
  ApmBro::MemoryLeakDetector.initialize_history
50
-
54
+
51
55
  # Install detailed memory tracking only if enabled
52
56
  if ApmBro.configuration.allocation_tracking_enabled
53
57
  require "apm_bro/memory_tracking_subscriber"
54
58
  ApmBro::MemoryTrackingSubscriber.subscribe!(client: ApmBro::Client.new)
55
59
  end
56
-
60
+
57
61
  # Install job tracking if ActiveJob is available
58
62
  if defined?(ActiveJob)
59
63
  require "apm_bro/job_subscriber"
@@ -61,15 +65,13 @@ module ApmBro
61
65
  ApmBro::JobSqlTrackingMiddleware.subscribe!
62
66
  ApmBro::JobSubscriber.subscribe!(client: ApmBro::Client.new)
63
67
  end
64
- rescue StandardError
68
+ rescue
65
69
  # Never raise in Railtie init
66
70
  end
67
71
  end
68
- end
69
72
 
70
- # Insert Rack middleware early enough to observe uncaught exceptions
71
- initializer "apm_bro.middleware" do |app|
72
- begin
73
+ # Insert Rack middleware early enough to observe uncaught exceptions
74
+ initializer "apm_bro.middleware" do |app|
73
75
  require "apm_bro/error_middleware"
74
76
 
75
77
  if defined?(::ActionDispatch::DebugExceptions)
@@ -79,21 +81,17 @@ module ApmBro
79
81
  else
80
82
  app.config.middleware.use(::ApmBro::ErrorMiddleware)
81
83
  end
82
- rescue StandardError
84
+ rescue
83
85
  # Never raise in Railtie init
84
86
  end
85
- end
86
87
 
87
- # Insert SQL tracking middleware
88
- initializer "apm_bro.sql_tracking_middleware" do |app|
89
- begin
88
+ # Insert SQL tracking middleware
89
+ initializer "apm_bro.sql_tracking_middleware" do |app|
90
90
  require "apm_bro/sql_tracking_middleware"
91
91
  app.config.middleware.use(::ApmBro::SqlTrackingMiddleware)
92
- rescue StandardError
92
+ rescue
93
93
  # Never raise in Railtie init
94
94
  end
95
95
  end
96
96
  end
97
97
  end
98
-
99
-
@@ -6,7 +6,7 @@ module ApmBro
6
6
 
7
7
  def self.subscribe!
8
8
  install_redis_instrumentation!
9
- rescue StandardError
9
+ rescue
10
10
  # Never raise from instrumentation install
11
11
  end
12
12
 
@@ -25,7 +25,7 @@ module ApmBro
25
25
  # Only instrument if Redis::Client actually has the call method
26
26
  # Check both public and private methods
27
27
  has_call = ::Redis::Client.instance_methods(false).include?(:call) ||
28
- ::Redis::Client.private_instance_methods(false).include?(:call)
28
+ ::Redis::Client.private_instance_methods(false).include?(:call)
29
29
  return unless has_call
30
30
 
31
31
  mod = Module.new do
@@ -41,7 +41,7 @@ module ApmBro
41
41
  end
42
42
  else
43
43
  # If not tracking, just pass through unchanged
44
- super(*args, &block)
44
+ super
45
45
  end
46
46
  end
47
47
 
@@ -63,7 +63,6 @@ module ApmBro
63
63
  return yield unless Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
64
64
 
65
65
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
66
- result = nil
67
66
  error = nil
68
67
  begin
69
68
  result = yield
@@ -90,7 +89,7 @@ module ApmBro
90
89
  if Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
91
90
  Thread.current[RedisSubscriber::THREAD_LOCAL_KEY] << event
92
91
  end
93
- rescue StandardError
92
+ rescue
94
93
  end
95
94
  end
96
95
  end
@@ -99,7 +98,6 @@ module ApmBro
99
98
  return yield unless Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
100
99
 
101
100
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
102
- result = nil
103
101
  begin
104
102
  result = yield
105
103
  result
@@ -119,7 +117,7 @@ module ApmBro
119
117
  if Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
120
118
  Thread.current[RedisSubscriber::THREAD_LOCAL_KEY] << event
121
119
  end
122
- rescue StandardError
120
+ rescue
123
121
  end
124
122
  end
125
123
  end
@@ -128,7 +126,6 @@ module ApmBro
128
126
  return yield unless Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
129
127
 
130
128
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
131
- result = nil
132
129
  begin
133
130
  result = yield
134
131
  result
@@ -148,7 +145,7 @@ module ApmBro
148
145
  if Thread.current[RedisSubscriber::THREAD_LOCAL_KEY]
149
146
  Thread.current[RedisSubscriber::THREAD_LOCAL_KEY] << event
150
147
  end
151
- rescue StandardError
148
+ rescue
152
149
  end
153
150
  end
154
151
  end
@@ -157,39 +154,41 @@ module ApmBro
157
154
  parts = Array(command).map(&:to_s)
158
155
  command_name = parts.first&.upcase
159
156
  key = parts[1]
160
- args_count = parts.length > 1 ? parts.length - 1 : 0
157
+ args_count = (parts.length > 1) ? parts.length - 1 : 0
161
158
 
162
159
  {
163
160
  command: safe_command(command_name),
164
161
  key: safe_key(key),
165
162
  args_count: args_count
166
163
  }
167
- rescue StandardError
168
- { command: nil, key: nil, args_count: nil }
164
+ rescue
165
+ {command: nil, key: nil, args_count: nil}
169
166
  end
170
167
 
171
168
  def safe_command(cmd)
172
169
  return nil if cmd.nil?
173
170
  cmd.to_s[0, 20]
174
- rescue StandardError
171
+ rescue
175
172
  nil
176
173
  end
177
174
 
178
175
  def safe_key(key)
179
176
  return nil if key.nil?
180
177
  s = key.to_s
181
- s.length > 200 ? s[0, 200] + "…" : s
182
- rescue StandardError
178
+ (s.length > 200) ? s[0, 200] + "…" : s
179
+ rescue
183
180
  nil
184
181
  end
185
182
 
186
183
  def safe_db(db)
187
- Integer(db) rescue nil
184
+ Integer(db)
185
+ rescue
186
+ nil
188
187
  end
189
188
  end
190
189
 
191
190
  ::Redis::Client.prepend(mod) unless ::Redis::Client.ancestors.include?(mod)
192
- rescue StandardError
191
+ rescue
193
192
  # Redis::Client may not be available or may have different structure
194
193
  end
195
194
 
@@ -204,7 +203,7 @@ module ApmBro
204
203
  event = build_event(name, data, duration_ms)
205
204
  Thread.current[THREAD_LOCAL_KEY] << event if event
206
205
  end
207
- rescue StandardError
206
+ rescue
208
207
  end
209
208
  end
210
209
  end
@@ -221,7 +220,7 @@ module ApmBro
221
220
 
222
221
  def self.build_event(name, data, duration_ms)
223
222
  cmd = extract_command(data)
224
- base = {
223
+ {
225
224
  event: name.to_s,
226
225
  command: cmd[:command],
227
226
  key: cmd[:key],
@@ -229,22 +228,21 @@ module ApmBro
229
228
  duration_ms: duration_ms,
230
229
  db: safe_db(data[:db])
231
230
  }
232
- base
233
- rescue StandardError
231
+ rescue
234
232
  nil
235
233
  end
236
234
 
237
235
  def self.extract_command(data)
238
- return { command: nil, key: nil, args_count: nil } unless data.is_a?(Hash)
236
+ return {command: nil, key: nil, args_count: nil} unless data.is_a?(Hash)
239
237
 
240
- if data[:command]
241
- parts = Array(data[:command]).map(&:to_s)
238
+ parts = if data[:command]
239
+ Array(data[:command]).map(&:to_s)
242
240
  elsif data[:commands]
243
- parts = Array(data[:commands]).flatten.map(&:to_s)
241
+ Array(data[:commands]).flatten.map(&:to_s)
244
242
  elsif data[:cmd]
245
- parts = Array(data[:cmd]).map(&:to_s)
243
+ Array(data[:cmd]).map(&:to_s)
246
244
  else
247
- parts = []
245
+ []
248
246
  end
249
247
 
250
248
  command_name = parts.first&.upcase
@@ -256,30 +254,29 @@ module ApmBro
256
254
  key: safe_key(key),
257
255
  args_count: args_count
258
256
  }
259
- rescue StandardError
260
- { command: nil, key: nil, args_count: nil }
257
+ rescue
258
+ {command: nil, key: nil, args_count: nil}
261
259
  end
262
260
 
263
261
  def self.safe_command(cmd)
264
262
  return nil if cmd.nil?
265
- s = cmd.to_s[0, 20]
266
- s
267
- rescue StandardError
263
+ cmd.to_s[0, 20]
264
+ rescue
268
265
  nil
269
266
  end
270
267
 
271
268
  def self.safe_key(key)
272
269
  return nil if key.nil?
273
270
  s = key.to_s
274
- s.length > 200 ? s[0, 200] + "…" : s
275
- rescue StandardError
271
+ (s.length > 200) ? s[0, 200] + "…" : s
272
+ rescue
276
273
  nil
277
274
  end
278
275
 
279
276
  def self.safe_db(db)
280
- Integer(db) rescue nil
277
+ Integer(db)
278
+ rescue
279
+ nil
281
280
  end
282
281
  end
283
282
  end
284
-
285
-