brainzlab 0.1.2 → 0.1.3

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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +6 -21
  3. data/README.md +16 -2
  4. data/lib/brainzlab/beacon/client.rb +38 -40
  5. data/lib/brainzlab/beacon/provisioner.rb +1 -1
  6. data/lib/brainzlab/beacon.rb +15 -15
  7. data/lib/brainzlab/configuration.rb +92 -90
  8. data/lib/brainzlab/context.rb +2 -3
  9. data/lib/brainzlab/cortex/client.rb +29 -31
  10. data/lib/brainzlab/cortex/provisioner.rb +1 -1
  11. data/lib/brainzlab/cortex.rb +7 -11
  12. data/lib/brainzlab/dendrite/client.rb +42 -44
  13. data/lib/brainzlab/dendrite/provisioner.rb +1 -1
  14. data/lib/brainzlab/dendrite.rb +4 -4
  15. data/lib/brainzlab/devtools/data/collector.rb +22 -22
  16. data/lib/brainzlab/devtools/middleware/asset_server.rb +14 -14
  17. data/lib/brainzlab/devtools/middleware/database_handler.rb +52 -55
  18. data/lib/brainzlab/devtools/middleware/debug_panel.rb +19 -19
  19. data/lib/brainzlab/devtools/middleware/error_page.rb +45 -44
  20. data/lib/brainzlab/devtools/renderers/debug_panel_renderer.rb +39 -35
  21. data/lib/brainzlab/devtools/renderers/error_page_renderer.rb +13 -9
  22. data/lib/brainzlab/devtools.rb +11 -11
  23. data/lib/brainzlab/flux/buffer.rb +3 -3
  24. data/lib/brainzlab/flux/client.rb +14 -16
  25. data/lib/brainzlab/flux/provisioner.rb +13 -13
  26. data/lib/brainzlab/flux.rb +8 -8
  27. data/lib/brainzlab/instrumentation/action_mailer.rb +14 -13
  28. data/lib/brainzlab/instrumentation/active_record.rb +13 -15
  29. data/lib/brainzlab/instrumentation/aws.rb +43 -39
  30. data/lib/brainzlab/instrumentation/dalli.rb +20 -20
  31. data/lib/brainzlab/instrumentation/delayed_job.rb +27 -29
  32. data/lib/brainzlab/instrumentation/elasticsearch.rb +23 -24
  33. data/lib/brainzlab/instrumentation/excon.rb +27 -27
  34. data/lib/brainzlab/instrumentation/faraday.rb +3 -4
  35. data/lib/brainzlab/instrumentation/good_job.rb +28 -28
  36. data/lib/brainzlab/instrumentation/grape.rb +24 -24
  37. data/lib/brainzlab/instrumentation/graphql.rb +24 -23
  38. data/lib/brainzlab/instrumentation/httparty.rb +13 -14
  39. data/lib/brainzlab/instrumentation/mongodb.rb +7 -7
  40. data/lib/brainzlab/instrumentation/net_http.rb +6 -6
  41. data/lib/brainzlab/instrumentation/redis.rb +14 -21
  42. data/lib/brainzlab/instrumentation/resque.rb +23 -24
  43. data/lib/brainzlab/instrumentation/sidekiq.rb +29 -28
  44. data/lib/brainzlab/instrumentation/solid_queue.rb +37 -41
  45. data/lib/brainzlab/instrumentation/stripe.rb +36 -37
  46. data/lib/brainzlab/instrumentation/typhoeus.rb +19 -17
  47. data/lib/brainzlab/instrumentation.rb +20 -20
  48. data/lib/brainzlab/nerve/client.rb +38 -40
  49. data/lib/brainzlab/nerve/provisioner.rb +1 -1
  50. data/lib/brainzlab/nerve.rb +6 -6
  51. data/lib/brainzlab/pulse/client.rb +15 -11
  52. data/lib/brainzlab/pulse/instrumentation.rb +61 -57
  53. data/lib/brainzlab/pulse/propagation.rb +28 -28
  54. data/lib/brainzlab/pulse/provisioner.rb +12 -12
  55. data/lib/brainzlab/pulse/tracer.rb +3 -3
  56. data/lib/brainzlab/pulse.rb +13 -13
  57. data/lib/brainzlab/rails/log_formatter.rb +127 -121
  58. data/lib/brainzlab/rails/log_subscriber.rb +70 -76
  59. data/lib/brainzlab/rails/railtie.rb +66 -89
  60. data/lib/brainzlab/recall/buffer.rb +1 -1
  61. data/lib/brainzlab/recall/client.rb +14 -10
  62. data/lib/brainzlab/recall/logger.rb +16 -18
  63. data/lib/brainzlab/recall/provisioner.rb +16 -16
  64. data/lib/brainzlab/recall.rb +11 -13
  65. data/lib/brainzlab/reflex/breadcrumbs.rb +2 -2
  66. data/lib/brainzlab/reflex/client.rb +14 -10
  67. data/lib/brainzlab/reflex/provisioner.rb +12 -12
  68. data/lib/brainzlab/reflex.rb +29 -29
  69. data/lib/brainzlab/sentinel/client.rb +40 -42
  70. data/lib/brainzlab/sentinel/provisioner.rb +1 -1
  71. data/lib/brainzlab/sentinel.rb +5 -5
  72. data/lib/brainzlab/signal/client.rb +12 -14
  73. data/lib/brainzlab/signal/provisioner.rb +12 -12
  74. data/lib/brainzlab/signal.rb +7 -7
  75. data/lib/brainzlab/synapse/client.rb +42 -44
  76. data/lib/brainzlab/synapse/provisioner.rb +1 -1
  77. data/lib/brainzlab/synapse.rb +6 -6
  78. data/lib/brainzlab/utilities/circuit_breaker.rb +37 -41
  79. data/lib/brainzlab/utilities/health_check.rb +53 -55
  80. data/lib/brainzlab/utilities/log_formatter.rb +38 -40
  81. data/lib/brainzlab/utilities/rate_limiter.rb +5 -5
  82. data/lib/brainzlab/utilities.rb +4 -4
  83. data/lib/brainzlab/vault/cache.rb +1 -1
  84. data/lib/brainzlab/vault/client.rb +39 -41
  85. data/lib/brainzlab/vault/provisioner.rb +1 -1
  86. data/lib/brainzlab/vault.rb +19 -25
  87. data/lib/brainzlab/version.rb +1 -1
  88. data/lib/brainzlab/vision/client.rb +20 -20
  89. data/lib/brainzlab/vision/provisioner.rb +21 -21
  90. data/lib/brainzlab/vision.rb +17 -19
  91. data/lib/brainzlab-sdk.rb +1 -1
  92. data/lib/brainzlab.rb +22 -24
  93. data/lib/generators/brainzlab/install/install_generator.rb +29 -27
  94. metadata +1 -1
@@ -4,7 +4,7 @@ module BrainzLab
4
4
  module DevTools
5
5
  module Middleware
6
6
  class DebugPanel
7
- HTML_CONTENT_TYPE = "text/html"
7
+ HTML_CONTENT_TYPE = 'text/html'
8
8
 
9
9
  def initialize(app)
10
10
  @app = app
@@ -38,24 +38,24 @@ module BrainzLab
38
38
  return false unless DevTools.debug_panel_enabled?
39
39
  return false unless DevTools.allowed_environment?
40
40
  return false unless DevTools.allowed_ip?(extract_ip(env))
41
- return false if asset_request?(env["PATH_INFO"])
42
- return false if devtools_asset_request?(env["PATH_INFO"])
41
+ return false if asset_request?(env['PATH_INFO'])
42
+ return false if devtools_asset_request?(env['PATH_INFO'])
43
43
  return false if turbo_stream_request?(env)
44
44
 
45
45
  true
46
46
  end
47
47
 
48
48
  def extract_ip(env)
49
- forwarded = env["HTTP_X_FORWARDED_FOR"]
50
- return forwarded.split(",").first.strip if forwarded
49
+ forwarded = env['HTTP_X_FORWARDED_FOR']
50
+ return forwarded.split(',').first.strip if forwarded
51
51
 
52
- env["REMOTE_ADDR"]
52
+ env['REMOTE_ADDR']
53
53
  end
54
54
 
55
55
  def injectable_response?(status, headers)
56
56
  return false unless status == 200
57
57
 
58
- content_type = headers["Content-Type"]
58
+ content_type = headers['Content-Type']
59
59
  return false unless content_type
60
60
 
61
61
  content_type.include?(HTML_CONTENT_TYPE)
@@ -78,11 +78,11 @@ module BrainzLab
78
78
  end
79
79
 
80
80
  def turbo_stream_request?(env)
81
- accept = env["HTTP_ACCEPT"] || ""
82
- accept.include?("text/vnd.turbo-stream.html")
81
+ accept = env['HTTP_ACCEPT'] || ''
82
+ accept.include?('text/vnd.turbo-stream.html')
83
83
  end
84
84
 
85
- def inject_panel(body, env, status, headers)
85
+ def inject_panel(body, _env, status, headers)
86
86
  # Collect all response body parts
87
87
  full_body = collect_body(body)
88
88
 
@@ -91,25 +91,25 @@ module BrainzLab
91
91
  data[:response] = {
92
92
  status: status,
93
93
  headers: headers.to_h,
94
- content_type: headers["Content-Type"]
94
+ content_type: headers['Content-Type']
95
95
  }
96
96
 
97
97
  # Render panel HTML
98
98
  panel_html = @renderer.render(data)
99
99
 
100
100
  # Inject before </body>
101
- if full_body.include?("</body>")
102
- full_body = full_body.sub("</body>", "#{panel_html}</body>")
103
- else
104
- # If no </body> tag, append at the end
105
- full_body = "#{full_body}#{panel_html}"
106
- end
101
+ full_body = if full_body.include?('</body>')
102
+ full_body.sub('</body>', "#{panel_html}</body>")
103
+ else
104
+ # If no </body> tag, append at the end
105
+ "#{full_body}#{panel_html}"
106
+ end
107
107
 
108
108
  [full_body]
109
109
  end
110
110
 
111
111
  def collect_body(body)
112
- full_body = +""
112
+ full_body = +''
113
113
  body.each { |part| full_body << part }
114
114
  body.close if body.respond_to?(:close)
115
115
  full_body
@@ -117,7 +117,7 @@ module BrainzLab
117
117
 
118
118
  def update_content_length(headers, body)
119
119
  headers = headers.to_h.dup
120
- headers["Content-Length"] = body.sum(&:bytesize).to_s
120
+ headers['Content-Length'] = body.sum(&:bytesize).to_s
121
121
  headers
122
122
  end
123
123
  end
@@ -19,7 +19,7 @@ module BrainzLab
19
19
  if status >= 400 && html_response?(headers) && !json_request?(env)
20
20
  # Check if this looks like Rails' default error page
21
21
  body_content = collect_body(body)
22
- if body_content.include?("Action Controller: Exception caught") || body_content.include?("background: #C00")
22
+ if body_content.include?('Action Controller: Exception caught') || body_content.include?('background: #C00')
23
23
  # Extract exception info from the page
24
24
  exception_info = extract_exception_from_html(body_content)
25
25
  if exception_info
@@ -30,41 +30,41 @@ module BrainzLab
30
30
  end
31
31
 
32
32
  [status, headers, body]
33
- rescue Exception => exception
33
+ rescue Exception => e
34
34
  # Don't intercept if request wants JSON
35
- return raise_exception(exception) if json_request?(env)
35
+ return raise_exception(e) if json_request?(env)
36
36
 
37
37
  # Still capture to Reflex if available
38
- capture_to_reflex(exception)
38
+ capture_to_reflex(e)
39
39
 
40
40
  # Collect debug data and render branded error page
41
- data = collect_debug_data(env, exception)
42
- render_error_page(exception, data)
41
+ data = collect_debug_data(env, e)
42
+ render_error_page(e, data)
43
43
  end
44
44
  end
45
45
 
46
46
  def html_response?(headers)
47
47
  # Handle both uppercase and lowercase header names
48
- content_type = headers["Content-Type"] || headers["content-type"] || ""
49
- content_type.to_s.downcase.include?("text/html")
48
+ content_type = headers['Content-Type'] || headers['content-type'] || ''
49
+ content_type.to_s.downcase.include?('text/html')
50
50
  end
51
51
 
52
52
  def extract_exception_from_html(body)
53
53
  # Try to extract exception class and message from Rails error page
54
- if match = body.match(/<h1>([^<]+)<\/h1>/)
54
+ if (match = body.match(%r{<h1>([^<]+)</h1>}))
55
55
  error_title = match[1]
56
56
  # Extract the exception message from the page
57
- if msg_match = body.match(/<pre[^>]*>([^<]+)<\/pre>/)
57
+ if (msg_match = body.match(%r{<pre[^>]*>([^<]+)</pre>}))
58
58
  error_message = msg_match[1]
59
59
  end
60
60
 
61
61
  # Try to extract backtrace from Rails 8 format
62
62
  # Format: <a class="trace-frames ...">path/to/file.rb:123:in 'method'</a>
63
63
  backtrace = []
64
- body.scan(/<a[^>]*class="trace-frames[^"]*"[^>]*>\s*([^<]+)\s*<\/a>/m) do |trace_match|
64
+ body.scan(%r{<a[^>]*class="trace-frames[^"]*"[^>]*>\s*([^<]+)\s*</a>}m) do |trace_match|
65
65
  line = trace_match[0].strip
66
66
  # Decode HTML entities
67
- line = line.gsub("&#39;", "'").gsub("&quot;", '"').gsub("&amp;", "&").gsub("&lt;", "<").gsub("&gt;", ">")
67
+ line = line.gsub('&#39;', "'").gsub('&quot;', '"').gsub('&amp;', '&').gsub('&lt;', '<').gsub('&gt;', '>')
68
68
  backtrace << line unless line.empty?
69
69
  end
70
70
 
@@ -78,12 +78,13 @@ module BrainzLab
78
78
 
79
79
  def decode_html_entities(str)
80
80
  return str unless str
81
- str.gsub("&#39;", "'")
82
- .gsub("&quot;", '"')
83
- .gsub("&amp;", "&")
84
- .gsub("&lt;", "<")
85
- .gsub("&gt;", ">")
86
- .gsub("&nbsp;", " ")
81
+
82
+ str.gsub('&#39;', "'")
83
+ .gsub('&quot;', '"')
84
+ .gsub('&amp;', '&')
85
+ .gsub('&lt;', '<')
86
+ .gsub('&gt;', '>')
87
+ .gsub('&nbsp;', ' ')
87
88
  end
88
89
 
89
90
  def collect_debug_data_from_info(env, info)
@@ -127,9 +128,9 @@ module BrainzLab
127
128
  [
128
129
  500,
129
130
  {
130
- "Content-Type" => "text/html; charset=utf-8",
131
- "Content-Length" => html.bytesize.to_s,
132
- "X-Content-Type-Options" => "nosniff"
131
+ 'Content-Type' => 'text/html; charset=utf-8',
132
+ 'Content-Length' => html.bytesize.to_s,
133
+ 'X-Content-Type-Options' => 'nosniff'
133
134
  },
134
135
  [html]
135
136
  ]
@@ -138,7 +139,7 @@ module BrainzLab
138
139
  private
139
140
 
140
141
  def collect_body(body)
141
- full_body = +""
142
+ full_body = +''
142
143
  body.each { |part| full_body << part }
143
144
  body.close if body.respond_to?(:close)
144
145
  full_body
@@ -153,19 +154,19 @@ module BrainzLab
153
154
  end
154
155
 
155
156
  def extract_ip(env)
156
- forwarded = env["HTTP_X_FORWARDED_FOR"]
157
- return forwarded.split(",").first.strip if forwarded
157
+ forwarded = env['HTTP_X_FORWARDED_FOR']
158
+ return forwarded.split(',').first.strip if forwarded
158
159
 
159
- env["REMOTE_ADDR"]
160
+ env['REMOTE_ADDR']
160
161
  end
161
162
 
162
163
  def json_request?(env)
163
- accept = env["HTTP_ACCEPT"] || ""
164
- content_type = env["CONTENT_TYPE"] || ""
164
+ accept = env['HTTP_ACCEPT'] || ''
165
+ content_type = env['CONTENT_TYPE'] || ''
165
166
 
166
- accept.include?("application/json") ||
167
- content_type.include?("application/json") ||
168
- env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
167
+ accept.include?('application/json') ||
168
+ content_type.include?('application/json') ||
169
+ env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
169
170
  end
170
171
 
171
172
  def capture_to_reflex(exception)
@@ -199,9 +200,9 @@ module BrainzLab
199
200
  request = defined?(ActionDispatch::Request) ? ActionDispatch::Request.new(env) : nil
200
201
 
201
202
  {
202
- method: request&.request_method || env["REQUEST_METHOD"],
203
- path: request&.path || env["PATH_INFO"],
204
- url: request&.url || env["REQUEST_URI"],
203
+ method: request&.request_method || env['REQUEST_METHOD'],
204
+ path: request&.path || env['PATH_INFO'],
205
+ url: request&.url || env['REQUEST_URI'],
205
206
  params: scrub_params(context&.request_params || extract_params(env)),
206
207
  headers: extract_headers(env),
207
208
  session: {}
@@ -228,8 +229,8 @@ module BrainzLab
228
229
  def extract_headers(env)
229
230
  headers = {}
230
231
  env.each do |key, value|
231
- if key.start_with?("HTTP_")
232
- header_name = key.sub("HTTP_", "").split("_").map(&:capitalize).join("-")
232
+ if key.start_with?('HTTP_')
233
+ header_name = key.sub('HTTP_', '').split('_').map(&:capitalize).join('-')
233
234
  headers[header_name] = value
234
235
  end
235
236
  end
@@ -243,7 +244,7 @@ module BrainzLab
243
244
 
244
245
  params.transform_values.with_index do |(key, value), _|
245
246
  if scrub_fields.include?(key.to_s.downcase)
246
- "[FILTERED]"
247
+ '[FILTERED]'
247
248
  elsif value.is_a?(Hash)
248
249
  scrub_params(value)
249
250
  else
@@ -277,14 +278,14 @@ module BrainzLab
277
278
  def in_app_frame?(file)
278
279
  return false unless file
279
280
 
280
- file.include?("/app/") && !file.include?("/vendor/") && !file.include?("/gems/")
281
+ file.include?('/app/') && !file.include?('/vendor/') && !file.include?('/gems/')
281
282
  end
282
283
 
283
284
  def extract_source_from_backtrace(backtrace_lines)
284
285
  return nil if backtrace_lines.empty?
285
286
 
286
287
  # Find the first in-app frame
287
- target_line = backtrace_lines.find { |line| in_app_frame?(line.split(":").first) }
288
+ target_line = backtrace_lines.find { |line| in_app_frame?(line.split(':').first) }
288
289
  target_line ||= backtrace_lines.first
289
290
 
290
291
  match = target_line.match(/\A(.+):(\d+)/)
@@ -317,7 +318,7 @@ module BrainzLab
317
318
  return nil unless exception.backtrace&.any?
318
319
 
319
320
  # Find the first in-app frame (application code, not gems/framework)
320
- target_line = exception.backtrace.find { |line| in_app_frame?(line.split(":").first) }
321
+ target_line = exception.backtrace.find { |line| in_app_frame?(line.split(':').first) }
321
322
  # Fall back to first frame if no in-app frame found
322
323
  target_line ||= exception.backtrace.first
323
324
 
@@ -349,10 +350,10 @@ module BrainzLab
349
350
 
350
351
  def collect_environment_info
351
352
  {
352
- rails_version: defined?(Rails::VERSION::STRING) ? Rails::VERSION::STRING : "N/A",
353
+ rails_version: defined?(::Rails::VERSION::STRING) ? ::Rails::VERSION::STRING : 'N/A',
353
354
  ruby_version: RUBY_VERSION,
354
355
  env: BrainzLab.configuration.environment,
355
- server: ENV["SERVER_SOFTWARE"] || "Unknown",
356
+ server: ENV['SERVER_SOFTWARE'] || 'Unknown',
356
357
  pid: Process.pid
357
358
  }
358
359
  end
@@ -363,9 +364,9 @@ module BrainzLab
363
364
  [
364
365
  500,
365
366
  {
366
- "Content-Type" => "text/html; charset=utf-8",
367
- "Content-Length" => html.bytesize.to_s,
368
- "X-Content-Type-Options" => "nosniff"
367
+ 'Content-Type' => 'text/html; charset=utf-8',
368
+ 'Content-Length' => html.bytesize.to_s,
369
+ 'X-Content-Type-Options' => 'nosniff'
369
370
  },
370
371
  [html]
371
372
  ]
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "erb"
4
- require "cgi"
5
- require "json"
3
+ require 'erb'
4
+ require 'cgi'
5
+ require 'json'
6
6
 
7
7
  module BrainzLab
8
8
  module DevTools
9
9
  module Renderers
10
10
  class DebugPanelRenderer
11
11
  def initialize
12
- @template_path = File.join(DevTools::ASSETS_PATH, "templates", "debug_panel.html.erb")
12
+ @template_path = File.join(DevTools::ASSETS_PATH, 'templates', 'debug_panel.html.erb')
13
13
  # Cache compiled ERB template to avoid file I/O on every request
14
14
  @cached_erb = nil
15
15
  @template_mtime = nil
@@ -47,7 +47,7 @@ module BrainzLab
47
47
  end
48
48
 
49
49
  def json_pretty(obj)
50
- return "" if obj.nil? || (obj.respond_to?(:empty?) && obj.empty?)
50
+ return '' if obj.nil? || (obj.respond_to?(:empty?) && obj.empty?)
51
51
 
52
52
  JSON.pretty_generate(obj)
53
53
  rescue StandardError
@@ -55,14 +55,14 @@ module BrainzLab
55
55
  end
56
56
 
57
57
  def truncate(text, length = 80)
58
- return "" unless text
58
+ return '' unless text
59
59
 
60
60
  text = text.to_s
61
61
  text.length > length ? "#{text[0...length]}..." : text
62
62
  end
63
63
 
64
64
  def format_duration(ms)
65
- return "0ms" unless ms
65
+ return '0ms' unless ms
66
66
 
67
67
  if ms >= 1000
68
68
  "#{(ms / 1000.0).round(2)}s"
@@ -72,78 +72,82 @@ module BrainzLab
72
72
  end
73
73
 
74
74
  def duration_class(ms)
75
- return "" unless ms
75
+ return '' unless ms
76
76
 
77
77
  if ms > 1000
78
- "very-slow"
78
+ 'very-slow'
79
79
  elsif ms > 500
80
- "slow"
80
+ 'slow'
81
81
  elsif ms > 200
82
- "moderate"
82
+ 'moderate'
83
83
  else
84
- ""
84
+ ''
85
85
  end
86
86
  end
87
87
 
88
88
  def query_duration_class(ms)
89
- return "" unless ms
89
+ return '' unless ms
90
90
 
91
91
  if ms > 100
92
- "very-slow"
92
+ 'very-slow'
93
93
  elsif ms > 50
94
- "slow"
94
+ 'slow'
95
95
  elsif ms > 10
96
- "moderate"
96
+ 'moderate'
97
97
  else
98
- ""
98
+ ''
99
99
  end
100
100
  end
101
101
 
102
102
  def status_class(status)
103
103
  case status
104
- when 200..299 then "success"
105
- when 300..399 then "redirect"
106
- when 400..499 then "client-error"
107
- when 500..599 then "server-error"
108
- else ""
104
+ when 200..299 then 'success'
105
+ when 300..399 then 'redirect'
106
+ when 400..499 then 'client-error'
107
+ when 500..599 then 'server-error'
108
+ else ''
109
109
  end
110
110
  end
111
111
 
112
112
  def log_level_class(level)
113
113
  case level.to_s.downcase
114
- when "error", "fatal" then "error"
115
- when "warn", "warning" then "warning"
116
- when "info" then "info"
117
- when "debug" then "debug"
118
- else ""
114
+ when 'error', 'fatal' then 'error'
115
+ when 'warn', 'warning' then 'warning'
116
+ when 'info' then 'info'
117
+ when 'debug' then 'debug'
118
+ else ''
119
119
  end
120
120
  end
121
121
 
122
122
  def format_timestamp(time)
123
- return "" unless time
123
+ return '' unless time
124
124
 
125
- time.strftime("%H:%M:%S.%L")
125
+ time.strftime('%H:%M:%S.%L')
126
126
  end
127
127
 
128
128
  def memory_class(delta_mb)
129
- return "" unless delta_mb
129
+ return '' unless delta_mb
130
130
 
131
131
  if delta_mb > 50
132
- "high"
132
+ 'high'
133
133
  elsif delta_mb > 20
134
- "moderate"
134
+ 'moderate'
135
135
  else
136
- ""
136
+ ''
137
137
  end
138
138
  end
139
139
 
140
140
  # Cache compiled ERB template, reloading only if file changed (dev mode)
141
141
  def cached_erb
142
- current_mtime = File.mtime(@template_path) rescue nil
142
+ current_mtime = begin
143
+ File.mtime(@template_path)
144
+ rescue StandardError
145
+ nil
146
+ end
143
147
 
144
148
  if @cached_erb.nil? || (current_mtime && current_mtime != @template_mtime)
145
149
  template = File.read(@template_path)
146
- @cached_erb = ERB.new(template, trim_mode: "-")
150
+ @cached_erb = ERB.new(template, trim_mode: '-')
147
151
  @template_mtime = current_mtime
148
152
  end
149
153
 
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "erb"
4
- require "cgi"
3
+ require 'erb'
4
+ require 'cgi'
5
5
 
6
6
  module BrainzLab
7
7
  module DevTools
8
8
  module Renderers
9
9
  class ErrorPageRenderer
10
10
  def initialize
11
- @template_path = File.join(DevTools::ASSETS_PATH, "templates", "error_page.html.erb")
11
+ @template_path = File.join(DevTools::ASSETS_PATH, 'templates', 'error_page.html.erb')
12
12
  @cached_erb = nil
13
13
  @template_mtime = nil
14
14
  end
@@ -40,10 +40,10 @@ module BrainzLab
40
40
  end
41
41
 
42
42
  def format_params(params, indent = 0)
43
- return "" if params.nil? || params.empty?
43
+ return '' if params.nil? || params.empty?
44
44
 
45
45
  lines = []
46
- prefix = " " * indent
46
+ prefix = ' ' * indent
47
47
 
48
48
  params.each do |key, value|
49
49
  if value.is_a?(Hash)
@@ -60,13 +60,13 @@ module BrainzLab
60
60
  end
61
61
 
62
62
  def truncate(text, length = 100)
63
- return "" unless text
63
+ return '' unless text
64
64
 
65
65
  text.length > length ? "#{text[0...length]}..." : text
66
66
  end
67
67
 
68
68
  def time_ago(time)
69
- return "unknown" unless time
69
+ return 'unknown' unless time
70
70
 
71
71
  seconds = Time.now.utc - time
72
72
  case seconds
@@ -78,11 +78,15 @@ module BrainzLab
78
78
 
79
79
  # Cache compiled ERB template, reloading only if file changed
80
80
  def cached_erb
81
- current_mtime = File.mtime(@template_path) rescue nil
81
+ current_mtime = begin
82
+ File.mtime(@template_path)
83
+ rescue StandardError
84
+ nil
85
+ end
82
86
 
83
87
  if @cached_erb.nil? || (current_mtime && current_mtime != @template_mtime)
84
88
  template = File.read(@template_path)
85
- @cached_erb = ERB.new(template, trim_mode: "-")
89
+ @cached_erb = ERB.new(template, trim_mode: '-')
86
90
  @template_mtime = current_mtime
87
91
  end
88
92
 
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "devtools/data/collector"
4
- require_relative "devtools/middleware/asset_server"
5
- require_relative "devtools/middleware/database_handler"
6
- require_relative "devtools/middleware/error_page"
7
- require_relative "devtools/middleware/debug_panel"
8
- require_relative "devtools/renderers/error_page_renderer"
9
- require_relative "devtools/renderers/debug_panel_renderer"
3
+ require_relative 'devtools/data/collector'
4
+ require_relative 'devtools/middleware/asset_server'
5
+ require_relative 'devtools/middleware/database_handler'
6
+ require_relative 'devtools/middleware/error_page'
7
+ require_relative 'devtools/middleware/debug_panel'
8
+ require_relative 'devtools/renderers/error_page_renderer'
9
+ require_relative 'devtools/renderers/debug_panel_renderer'
10
10
 
11
11
  module BrainzLab
12
12
  module DevTools
13
- ASSETS_PATH = File.expand_path("devtools/assets", __dir__)
13
+ ASSETS_PATH = File.expand_path('devtools/assets', __dir__)
14
14
 
15
15
  class << self
16
16
  def enabled?
@@ -33,7 +33,7 @@ module BrainzLab
33
33
 
34
34
  def allowed_ip?(request_ip)
35
35
  # Skip IP checking in development - environment check is enough
36
- return true if BrainzLab.configuration.environment == "development"
36
+ return true if BrainzLab.configuration.environment == 'development'
37
37
 
38
38
  return true if BrainzLab.configuration.devtools_allowed_ips.empty?
39
39
 
@@ -42,7 +42,7 @@ module BrainzLab
42
42
 
43
43
  # Check CIDR ranges
44
44
  allowed_ips.any? do |ip|
45
- if ip.include?("/")
45
+ if ip.include?('/')
46
46
  ip_in_cidr?(request_ip, ip)
47
47
  else
48
48
  ip == request_ip
@@ -65,7 +65,7 @@ module BrainzLab
65
65
  private
66
66
 
67
67
  def ip_in_cidr?(ip, cidr)
68
- require "ipaddr"
68
+ require 'ipaddr'
69
69
  IPAddr.new(cidr).include?(IPAddr.new(ip))
70
70
  rescue IPAddr::InvalidAddressError
71
71
  false
@@ -75,7 +75,7 @@ module BrainzLab
75
75
  return if events.empty? && metrics.empty?
76
76
 
77
77
  @client.send_batch(events: events, metrics: metrics)
78
- rescue => e
78
+ rescue StandardError => e
79
79
  BrainzLab.debug("[Flux] Batch send failed: #{e.message}")
80
80
  end
81
81
 
@@ -84,8 +84,8 @@ module BrainzLab
84
84
  loop do
85
85
  sleep FLUSH_INTERVAL
86
86
  begin
87
- flush! if size > 0
88
- rescue => e
87
+ flush! if size.positive?
88
+ rescue StandardError => e
89
89
  BrainzLab.debug("[Flux] Flush thread error: #{e.message}")
90
90
  end
91
91
  end