rails_performance 1.4.2 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d387037eea90f299a14499105f68cd78794ee7a36122d45081c488b9ca3fb6dd
4
- data.tar.gz: 1c49de1b612f86f8089fdd2765b53bcbdddb2bb65d4890eacdf068f0ca14ecc3
3
+ metadata.gz: 60fc2568e878c07db112623ef55985422852996f3eea18fd972c9ccc0288fd1a
4
+ data.tar.gz: 3ff0036deb507e91fd9ac1ab63cafac95e98aeb59646ca566dff403a2bcdc1d6
5
5
  SHA512:
6
- metadata.gz: 208578b1cc4a8a4b261c9607d89b045983ab2be0cc1ef811059be38a3c02dd4f9b333a0937900733b04ad8058c1c920c02f333bc31b9fae13c1629123456a99d
7
- data.tar.gz: 9066e380c0d9309554e7574298d8bda95570e4f0851fdfa586c675f998bcdfaed993decd336d9de4c6b1b6ed55b0065fc368aba8ba23c7627690db18bedae36b
6
+ metadata.gz: 28a6b7d3918eaabb97a4cabcdbc95e66cca45dba61c416f90ed083e6508df79333a0e2c209fb3d1d1654a1516587dda5387eb88a42518a4b602cb77b4c83922e
7
+ data.tar.gz: '0179ca0fdece9492e9053820aa025d0210391957d9eee2cac714bc0e8611003b467ff8d06bf91cb27d0eb8024bc4a8d77a56410aa7879a701be0d9df59ed8ee1'
data/README.md CHANGED
@@ -45,7 +45,7 @@ All data are stored in `local` Redis and not sent to any 3rd party servers.
45
45
 
46
46
  ## Production
47
47
 
48
- Gem is production-ready. At least on my 2 applications with ~800 unique users per day it works perfectly.
48
+ Gem is production-ready. At least in my 2 applications with ~800 unique users per day it works perfectly.
49
49
 
50
50
  Just don't forget to protect performance dashboard with http basic auth or check of current_user.
51
51
 
@@ -68,7 +68,7 @@ RailsPerformance.setup do |config|
68
68
  config.redis = Redis.new(url: ENV["REDIS_URL"].presence || "redis://127.0.0.1:6379/0") # or Redis::Namespace.new("rails-performance", redis: Redis.new), see below in README
69
69
  config.duration = 4.hours
70
70
 
71
- config.debug = false # currently not used>
71
+ config.debug = false # currently not used
72
72
  config.enabled = true
73
73
 
74
74
  # configure Recent tab (time window and limit of requests)
@@ -172,6 +172,7 @@ After installation and configuration, start your Rails application, make a few r
172
172
 
173
173
  If you, for whatever reason (company policy, devise, ...) need to mount RailsPerformance yourself, feel free to do so by using the following snippet as inspiration.
174
174
  You can skip the `mount_at` and `http_basic_authentication_*` configurations then, if you like.
175
+ Under certain constraints (i.e. subdomains) it may be necessary to set `url_options` in the config so that RailsPeformance can generate links correctly.
175
176
 
176
177
  ```ruby
177
178
  # config/routes.rb
@@ -223,10 +224,10 @@ env:
223
224
  RAILS_PERFORMANCE_SERVER_ID: "server"
224
225
  ```
225
226
 
226
- You can also specifify custom "context" and "role" for monitoring, by changing the env variables:
227
+ You can also specify custom "context" and "role" for monitoring, by changing the env variables:
227
228
 
228
229
  ```ruby
229
- RailsPerformance::Extensions::ResourceMonitor.new(
230
+ RailsPerformance::SystemMonitor::ResourcesMonitor.new(
230
231
  ENV["RAILS_PERFORMANCE_SERVER_CONTEXT"].presence || "rails",
231
232
  ENV["RAILS_PERFORMANCE_SERVER_ROLE"].presence || "web"
232
233
  )
@@ -323,6 +324,15 @@ The idea of this gem grew from curiosity how many RPM my app receiving per day.
323
324
  - sinatra?
324
325
  - tests to check what is actually stored in redis db after request
325
326
  - upgrade bulma
327
+ - optimize svg icons, remove inline svg (switch to base64 or assets)
328
+
329
+ ## Development
330
+
331
+ 1. Clone the repo
332
+ 2. Run `bundle install`
333
+ 3. Setup dummy app `cd test/dummy && bundle install && rails db:create && rails db:migrate`
334
+ 4. Run `rails s` in the root folder
335
+ 5. Run `rails test` to run tests
326
336
 
327
337
  ## Contributing
328
338
 
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
2
+ <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
3
+ </svg>
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path d="M0 0h24v24H0z" fill="none"/><path d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6zm11-3v8h-2V6.413l-7.793 7.794-1.414-1.414L17.585 5H13V3h8z"/></g></svg>
@@ -12,6 +12,10 @@ module RailsPerformance
12
12
  password: RailsPerformance.http_basic_authentication_password
13
13
  end
14
14
 
15
+ def url_options
16
+ RailsPerformance.url_options.nil? ? super : RailsPerformance.url_options
17
+ end
18
+
15
19
  private
16
20
 
17
21
  def verify_access
@@ -6,6 +6,7 @@ function showChart(element_id, type, title, options) {
6
6
  chart: {
7
7
  type: type,
8
8
  height: 300,
9
+ width: '100%',
9
10
  zoom: {
10
11
  type: 'x',
11
12
  },
@@ -9,12 +9,24 @@
9
9
  <td><%= format_datetime e[:datetime] %></td>
10
10
  <td>
11
11
  <% controller_action_info = e[:controller] + '#' + e[:action]%>
12
- <%= link_to truncate(controller_action_info, length: 40), rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true, title: controller_action_info %>
12
+ <%= link_to rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true, title: controller_action_info do %>
13
+ <span class="details_icon">
14
+ <%= icon 'details' %>
15
+ </span>
16
+ <%= truncate(controller_action_info, length: 40) %>
17
+ <% end %>
13
18
  </td>
14
19
  <td><%= e[:method] %></td>
15
20
  <td><%= e[:format] %></td>
16
21
  <td><%= bot_icon e["user_agent"] %></td>
17
- <td><%= link_to_path(e) %></td>
22
+ <td>
23
+ <span class="with_external_icon">
24
+ <%= link_to_path(e) %>
25
+ <span class="icon external_icon">
26
+ <%= icon('external') %>
27
+ </span>
28
+ </span>
29
+ </td>
18
30
  <td><%= status_tag e[:status] %></td>
19
31
  <td class="nowrap"><%= ms e[:duration] %></td>
20
32
  <td class="nowrap"><%= ms e[:view_runtime] %></td>
@@ -5,7 +5,7 @@
5
5
  <div id="response_time_report_chart_mini" class="chart_mini"></div>
6
6
 
7
7
  <h2 class="subtitle"><%= title %></h2>
8
- <table class="table is-fullwidth is-hoverable is-narrow is-size-9">
8
+ <table class="table is-fullwidth is-hoverable is-narrow is-size-8">
9
9
  <thead>
10
10
  <tr>
11
11
  <th data-sort="string">Datetime</th>
@@ -25,7 +25,14 @@
25
25
  <td><%= format_datetime e[:datetime] %></td>
26
26
  <td><%= e[:method] %></td>
27
27
  <td><%= bot_icon e["user_agent"] %></td>
28
- <td><%= link_to_path(e) %></td>
28
+ <td>
29
+ <span class="with_external_icon">
30
+ <%= link_to_path(e) %>
31
+ <span class="icon external_icon">
32
+ <%= icon('external') %>
33
+ </span>
34
+ </span>
35
+ </td>
29
36
  <td><%= e[:format] %></td>
30
37
  <td><%= status_tag e[:status] %></td>
31
38
  <td class="nowrap"><%= ms e[:duration] %></td>
@@ -35,11 +35,25 @@
35
35
  <% @data.each do |e| %>
36
36
  <tr>
37
37
  <td><%= format_datetime e[:datetime] %></td>
38
- <td><%= link_to e[:controller] + '#' + e[:action], rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true %></td>
38
+ <td>
39
+ <%= link_to rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true do %>
40
+ <span class="details_icon">
41
+ <%= icon 'details' %>
42
+ </span>
43
+ <%= e[:controller] + '#' + e[:action] %>
44
+ <% end %>
45
+ </td>
39
46
  <td><%= e[:method] %></td>
40
47
  <td><%= e[:format] %></td>
41
48
  <td><%= bot_icon e["user_agent"] %></td>
42
- <td><%= link_to_path(e) %></td>
49
+ <td>
50
+ <span class="with_external_icon">
51
+ <%= link_to_path(e) %>
52
+ <span class="icon external_icon">
53
+ <%= icon('external') %>
54
+ </span>
55
+ </span>
56
+ </td>
43
57
  <td><%= e[:exception] %></td>
44
58
  <td class="very-small-text">
45
59
  <%= raw e[:backtrace]&.join("<br/>") %>
@@ -36,7 +36,14 @@
36
36
  <% groups = e[:group].split("|") %>
37
37
  <% c, a = groups[0].split("#") %>
38
38
  <tr>
39
- <td><%= link_to groups[0], rails_performance.rails_performance_summary_path({controller_eq: c, action_eq: a}), remote: true %></td>
39
+ <td>
40
+ <%= link_to rails_performance.rails_performance_summary_path({controller_eq: c, action_eq: a}), remote: true do %>
41
+ <span class="details_icon">
42
+ <%= icon 'details' %>
43
+ </span>
44
+ <%= groups[0] %>
45
+ <% end %>
46
+ </td>
40
47
  <td><%= link_to groups[1].try(:upcase), rails_performance.rails_performance_summary_path({controller_eq: c, action_eq: a, format_eq: groups[1]}), remote: true %></td>
41
48
  <td><%= e[:count] %></td>
42
49
  <td class="nowrap attention"><%= ms e[:p50_duration] %></td>
@@ -1,50 +1,23 @@
1
1
  <title>System Resources</title>
2
2
 
3
- <% @resources_report.data.keys.each do |server_key| %>
4
- <h1 class="title mt-8 pt-8"><%= server_key.split("///"). join(", ") %></h1>
5
-
6
- <div class="card">
7
- <div class="card-content">
8
- <h2 class="subtitle">CPU</h2>
9
- <div id="cpu_report_<%= server_key.parameterize %>" class="chart"></div>
10
- <p class="content is-small">CPU usage %, average per 1 minute</p>
11
- </div>
12
- </div>
13
-
14
- <br/>
15
-
16
- <div class="card">
17
- <div class="card-content">
18
- <h2 class="subtitle">Memory</h2>
19
- <div id="memory_report_<%= server_key.parameterize %>" class="chart"></div>
20
- <p class="content is-small">App memory usage</p>
21
- </div>
22
- </div>
23
-
24
- <br/>
25
-
26
- <div class="card">
27
- <div class="card-content">
28
- <h2 class="subtitle">Storage</h2>
29
- <div id="disk_report_<%= server_key.parameterize %>" class="chart"></div>
30
- <p class="content is-small">Available storage size (local disk size)</p>
3
+ <% @resources_report.servers.each do |server| %>
4
+ <h1 class="title mt-8 pt-8"><%= server.name %></h1>
5
+
6
+ <% server.charts.each.with_index do |chart, index| %>
7
+ <div class="card">
8
+ <div class="card-content">
9
+ <h2 class="subtitle"><%= chart.subtitle %></h2>
10
+ <div class="chart" id="<%= chart.id %>"></div>
11
+ <p class="content is-small"><%= chart.description %></p>
12
+ </div>
31
13
  </div>
32
- </div>
33
-
34
- <br>
35
- <% end %>
36
-
37
- <% content_for :on_load do %>
38
- <script>
39
- <% @resources_report.data.keys.each do |server_key| %>
40
- var data1 = <%= raw @resources_report.cpu[server_key].to_json %>;
41
- showPercentageChart('cpu_report_<%= server_key.parameterize %>', data1, 'CPU');
42
14
 
43
- var data2 = <%= raw @resources_report.memory[server_key].to_json %>;
44
- showUsageChart('memory_report_<%= server_key.parameterize %>', data2, 'Usage', 2);
15
+ <br/>
45
16
 
46
- var data3 = <%= raw @resources_report.disk[server_key].to_json %>;
47
- showUsageChart('disk_report_<%= server_key.parameterize %>', data3, 'Available', 3);
17
+ <% content_for :on_load do %>
18
+ <script>
19
+ show<%= chart.type %>Chart('<%= chart.id %>', <%= raw chart.data.to_json %>, '<%= chart.legend %>', <%= index %>);
20
+ </script>
48
21
  <% end %>
49
- </script>
22
+ <% end %>
50
23
  <% end %>
@@ -32,13 +32,25 @@
32
32
  .cd-panel__container {
33
33
  z-index: 100;
34
34
  position: fixed;
35
- width: 800px;
35
+ width: 1200px;
36
36
  height: 100%;
37
37
  top: 0;
38
38
  transition: transform 0.3s 0s;
39
39
  overflow: scroll;
40
40
  }
41
41
 
42
+ @media (max-width: 1200px) {
43
+ .cd-panel__container {
44
+ width: 800px;
45
+ }
46
+ }
47
+
48
+ @media (max-width: 768px) {
49
+ .cd-panel__container {
50
+ width: 500px;
51
+ }
52
+ }
53
+
42
54
  .cd-panel--from-right .cd-panel__container {
43
55
  right: 0;
44
56
  transform: translate3d(100%, 0, 0);
@@ -57,4 +69,4 @@
57
69
  .cd-panel__container .panel {
58
70
  background: white;
59
71
  min-height: 100vh;
60
- }
72
+ }
@@ -62,6 +62,33 @@
62
62
  color: red;
63
63
  }
64
64
 
65
+ .external_icon svg {
66
+ width: 12px;
67
+ height: 12px;
68
+ color: #eee;
69
+ margin-left: -4px;
70
+ opacity: 0;
71
+ }
72
+
73
+ .details_icon {
74
+ position: relative;
75
+ width: 14px;
76
+ height: 14px;
77
+ }
78
+
79
+ .details_icon svg {
80
+ position: relative;
81
+ top: 2px;
82
+ width: 14px;
83
+ height: 14px;
84
+ }
85
+
86
+ .with_external_icon:hover {
87
+ .external_icon svg {
88
+ opacity: 1;
89
+ }
90
+ }
91
+
65
92
  .user-agent-icon svg {
66
93
  width: 12px;
67
94
  height: 12px;
@@ -77,7 +104,19 @@
77
104
 
78
105
  .chart_mini {
79
106
  height: 200px;
80
- width: 720px;
107
+ width: 1160px;
108
+ }
109
+
110
+ @media (max-width: 1200px) {
111
+ .chart_mini {
112
+ width: 770px;
113
+ }
114
+ }
115
+
116
+ @media (max-width: 768px) {
117
+ .chart_mini {
118
+ width: 400px;
119
+ }
81
120
  }
82
121
 
83
122
  .red {
@@ -31,6 +31,9 @@ if defined?(RailsPerformance)
31
31
  # for example when you have `current_user`
32
32
  # config.verify_access_proc = proc { |controller| controller.current_user && controller.current_user.admin? }
33
33
 
34
+ # Override engine url options, necessary if hosting under a unique domain
35
+ # config.url_options = {host: "sub.example.com"}
36
+
34
37
  # You can ignore endpoints with Rails standard notation controller#action
35
38
  # config.ignored_endpoints = ['HomeController#contact']
36
39
 
@@ -2,7 +2,7 @@ require "action_view/log_subscriber"
2
2
  require_relative "rails/middleware"
3
3
  require_relative "models/collection"
4
4
  require_relative "instrument/metrics_collector"
5
- require_relative "extensions/resources_monitor"
5
+ require_relative "system_monitor/resources_monitor"
6
6
 
7
7
  module RailsPerformance
8
8
  class Engine < ::Rails::Engine
@@ -16,7 +16,7 @@ module RailsPerformance
16
16
  next if $rails_performance_running_mode == :console # rubocop:disable Style/GlobalVars
17
17
 
18
18
  # start monitoring
19
- RailsPerformance._resource_monitor = RailsPerformance::Extensions::ResourceMonitor.new(
19
+ RailsPerformance._resource_monitor = RailsPerformance::SystemMonitor::ResourcesMonitor.new(
20
20
  ENV["RAILS_PERFORMANCE_SERVER_CONTEXT"].presence || "rails",
21
21
  ENV["RAILS_PERFORMANCE_SERVER_ROLE"].presence || "web"
22
22
  )
@@ -44,7 +44,7 @@ module RailsPerformance
44
44
  RailsPerformance._resource_monitor.stop_monitoring
45
45
  RailsPerformance._resource_monitor = nil
46
46
  # start background monitoring
47
- RailsPerformance._resource_monitor = RailsPerformance::Extensions::ResourceMonitor.new(
47
+ RailsPerformance._resource_monitor = RailsPerformance::SystemMonitor::ResourcesMonitor.new(
48
48
  ENV["RAILS_PERFORMANCE_SERVER_CONTEXT"].presence || "sidekiq",
49
49
  ENV["RAILS_PERFORMANCE_SERVER_ROLE"].presence || "background"
50
50
  )
@@ -26,16 +26,13 @@ module RailsPerformance
26
26
  end
27
27
 
28
28
  def record_hash
29
- {
29
+ value.symbolize_keys.merge({
30
30
  server: server,
31
31
  role: role,
32
32
  context: context,
33
33
  datetime: datetime,
34
- datetimei: RailsPerformance::Utils.from_datetimei(datetimei.to_i),
35
- cpu: value["cpu"],
36
- memory: value["memory"],
37
- disk: value["disk"]
38
- }
34
+ datetimei: RailsPerformance::Utils.from_datetimei(datetimei.to_i)
35
+ })
39
36
  end
40
37
 
41
38
  def save
@@ -1,40 +1,42 @@
1
1
  module RailsPerformance
2
2
  module Reports
3
3
  class ResourcesReport < BaseReport
4
- def data
5
- @data ||= db.data
6
- .collect { |e| e.record_hash }
7
- .group_by { |e| e[:server] + "///" + e[:context] + "///" + e[:role] }
8
- # .transform_values { |v| v.sort { |a, b| b[sort] <=> a[sort] } }
9
- .transform_values { |v| v.map { |e| e.merge({datetimei: e[:datetimei].to_i}) } }
10
- end
4
+ Server = Struct.new(:report, :key) do
5
+ def name
6
+ key.split("///").join(", ")
7
+ end
11
8
 
12
- def cpu
13
- @cpu ||= data.transform_values do |v|
14
- prepare_report(v.each_with_object({}) do |e, res|
15
- res[e[:datetimei] * 1000] = e[:cpu]["one_min"].to_f.round(2)
16
- end)
9
+ def charts
10
+ RailsPerformance.system_monitors.map do |class_name|
11
+ SystemMonitor.const_get(class_name).new(self)
12
+ end
17
13
  end
18
14
  end
19
15
 
20
- def memory
21
- @memory ||= data.transform_values do |v|
22
- prepare_report(v.each_with_object({}) do |e, res|
23
- res[e[:datetimei] * 1000] = e[:memory].to_f.round(2)
24
- end)
16
+ def servers
17
+ data.keys.map do |key|
18
+ Server.new(self, key)
25
19
  end
26
20
  end
27
21
 
28
- def disk
29
- @disk ||= data.transform_values do |v|
22
+ def extract_signal &block
23
+ data.transform_values do |v|
30
24
  prepare_report(v.each_with_object({}) do |e, res|
31
- res[e[:datetimei] * 1000] = e[:disk]["available"].to_f.round(2)
25
+ res[e[:datetimei] * 1000] = block.call(e)
32
26
  end)
33
27
  end
34
28
  end
35
29
 
36
30
  private
37
31
 
32
+ def data
33
+ @data ||= db.data
34
+ .collect { |e| e.record_hash }
35
+ .group_by { |e| e[:server] + "///" + e[:context] + "///" + e[:role] }
36
+ # .transform_values { |v| v.sort { |a, b| b[sort] <=> a[sort] } }
37
+ .transform_values { |v| v.map { |e| e.merge({datetimei: e[:datetimei].to_i}) } }
38
+ end
39
+
38
40
  def prepare_report(input)
39
41
  nullify_data(input, RailsPerformance.system_monitor_duration)
40
42
  end
@@ -0,0 +1,105 @@
1
+ module RailsPerformance
2
+ module SystemMonitor
3
+ ResourceChart = Struct.new(:server, :key, :type, :subtitle, :description, :legend, keyword_init: true) do
4
+ def id
5
+ [key, "report", server.key.parameterize].join("_")
6
+ end
7
+
8
+ def data
9
+ all_data = server.report.extract_signal { |e| signal(e) }
10
+ all_data[server.key]
11
+ end
12
+
13
+ def signal e
14
+ format(e[key])
15
+ end
16
+
17
+ def format measurement
18
+ measurement
19
+ end
20
+ end
21
+
22
+ class CPULoad < ResourceChart
23
+ def initialize server
24
+ super(
25
+ server:,
26
+ key: :cpu,
27
+ type: "Percentage",
28
+ subtitle: "CPU",
29
+ description: "CPU load average (1 min), average per 1 minute",
30
+ legend: "CPU",
31
+ )
32
+ end
33
+
34
+ def format measurement
35
+ measurement["one_min"].to_f.round(2)
36
+ end
37
+
38
+ def measure
39
+ load_averages = Sys::CPU.load_avg
40
+ {
41
+ one_min: load_averages[0],
42
+ five_min: load_averages[1],
43
+ fifteen_min: load_averages[2]
44
+ }
45
+ rescue => e
46
+ ::Rails.logger.error "Error fetching CPU usage: #{e.message}"
47
+ {one_min: 0.0, five_min: 0.0, fifteen_min: 0.0}
48
+ end
49
+ end
50
+
51
+ class MemoryUsage < ResourceChart
52
+ def initialize server
53
+ super(
54
+ server:,
55
+ key: :memory,
56
+ type: "Usage",
57
+ subtitle: "Memory",
58
+ description: "App memory usage",
59
+ legend: "Usage",
60
+ )
61
+ end
62
+
63
+ def format measurement
64
+ measurement.to_f.round(2)
65
+ end
66
+
67
+ def measure
68
+ GetProcessMem.new.bytes
69
+ rescue => e
70
+ ::Rails.logger.error "Error fetching memory usage: #{e.message}"
71
+ 0
72
+ end
73
+ end
74
+
75
+ class DiskUsage < ResourceChart
76
+ def initialize server
77
+ super(
78
+ server:,
79
+ key: :disk,
80
+ type: "Usage",
81
+ subtitle: "Storage",
82
+ description: "Available storage size (local disk size)",
83
+ legend: "Usage",
84
+ )
85
+ end
86
+
87
+ def signal measurement
88
+ measurement["available"].to_f.round(2)
89
+ end
90
+
91
+ def measure
92
+ path = "/"
93
+ stat = Sys::Filesystem.stat(path)
94
+ {
95
+ available: stat.blocks_available * stat.block_size,
96
+ total: stat.blocks * stat.block_size,
97
+ used: (stat.blocks - stat.blocks_available) * stat.block_size
98
+ }
99
+ rescue => e
100
+ ::Rails.logger.error "Error fetching disk space: #{e.message}"
101
+ {available: 0, total: 0, used: 0}
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,6 +1,8 @@
1
+ require "rails_performance/system_monitor/resource_chart"
2
+
1
3
  module RailsPerformance
2
- module Extensions
3
- class ResourceMonitor
4
+ module SystemMonitor
5
+ class ResourcesMonitor
4
6
  attr_reader :context, :role
5
7
 
6
8
  def initialize(context, role)
@@ -39,43 +41,20 @@ module RailsPerformance
39
41
  end
40
42
  end
41
43
 
42
- def run
43
- cpu = fetch_process_cpu_usage
44
- memory = fetch_process_memory_usage
45
- disk = fetch_disk_usage
46
-
47
- store_data({cpu: cpu, memory: memory, disk: disk})
48
- end
49
-
50
- def fetch_process_cpu_usage
51
- load_averages = Sys::CPU.load_avg
52
- {
53
- one_min: load_averages[0],
54
- five_min: load_averages[1],
55
- fifteen_min: load_averages[2]
56
- }
57
- rescue => e
58
- ::Rails.logger.error "Error fetching CPU usage: #{e.message}"
59
- {one_min: 0.0, five_min: 0.0, fifteen_min: 0.0}
44
+ def payload
45
+ monitors.reduce({}) do |data, monitor|
46
+ data.merge(monitor.key => monitor.measure)
47
+ end
60
48
  end
61
49
 
62
- def fetch_process_memory_usage
63
- GetProcessMem.new.bytes
64
- rescue => e
65
- ::Rails.logger.error "Error fetching memory usage: #{e.message}"
66
- 0
50
+ def monitors
51
+ @monitors ||= RailsPerformance.system_monitors.map do |class_name|
52
+ RailsPerformance::SystemMonitor.const_get(class_name).new(nil)
53
+ end
67
54
  end
68
55
 
69
- def fetch_disk_usage(path = "/")
70
- stat = Sys::Filesystem.stat(path)
71
- {
72
- available: stat.blocks_available * stat.block_size,
73
- total: stat.blocks * stat.block_size,
74
- used: (stat.blocks - stat.blocks_available) * stat.block_size
75
- }
76
- rescue => e
77
- ::Rails.logger.error "Error fetching disk space: #{e.message}"
78
- {available: 0, total: 0, used: 0}
56
+ def run
57
+ store_data(payload)
79
58
  end
80
59
 
81
60
  def store_data(data)
@@ -1,4 +1,4 @@
1
1
  module RailsPerformance
2
- VERSION = "1.4.2"
2
+ VERSION = "1.4.3"
3
3
  SCHEMA = "1.0.2"
4
4
  end
@@ -119,10 +119,20 @@ module RailsPerformance
119
119
  mattr_accessor :ignore_trace_headers
120
120
  @@ignore_trace_headers = ["datetimei"]
121
121
 
122
+ mattr_accessor :url_options
123
+ @@url_options = nil
124
+
122
125
  # System monitor duration (expiration time)
123
126
  mattr_accessor :system_monitor_duration
124
127
  @@system_monitor_duration = 24.hours
125
128
 
129
+ mattr_accessor :system_monitors
130
+ @@system_monitors = [
131
+ "CPULoad",
132
+ "MemoryUsage",
133
+ "DiskUsage"
134
+ ]
135
+
126
136
  # -- internal usage --
127
137
  #
128
138
  #
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-28 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: railties
@@ -290,8 +290,10 @@ files:
290
290
  - app/assets/images/activity.svg
291
291
  - app/assets/images/bot.svg
292
292
  - app/assets/images/close.svg
293
+ - app/assets/images/details.svg
293
294
  - app/assets/images/download.svg
294
295
  - app/assets/images/export.svg
296
+ - app/assets/images/external.svg
295
297
  - app/assets/images/git.svg
296
298
  - app/assets/images/github.svg
297
299
  - app/assets/images/home.svg
@@ -345,7 +347,6 @@ files:
345
347
  - lib/rails_performance.rb
346
348
  - lib/rails_performance/data_source.rb
347
349
  - lib/rails_performance/engine.rb
348
- - lib/rails_performance/extensions/resources_monitor.rb
349
350
  - lib/rails_performance/extensions/trace.rb
350
351
  - lib/rails_performance/gems/custom_ext.rb
351
352
  - lib/rails_performance/gems/delayed_job_ext.rb
@@ -376,6 +377,8 @@ files:
376
377
  - lib/rails_performance/reports/slow_requests_report.rb
377
378
  - lib/rails_performance/reports/throughput_report.rb
378
379
  - lib/rails_performance/reports/trace_report.rb
380
+ - lib/rails_performance/system_monitor/resource_chart.rb
381
+ - lib/rails_performance/system_monitor/resources_monitor.rb
379
382
  - lib/rails_performance/thread/current_request.rb
380
383
  - lib/rails_performance/utils.rb
381
384
  - lib/rails_performance/version.rb
@@ -397,7 +400,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
397
400
  - !ruby/object:Gem::Version
398
401
  version: '0'
399
402
  requirements: []
400
- rubygems_version: 3.6.3
403
+ rubygems_version: 3.6.9
401
404
  specification_version: 4
402
405
  summary: Simple Rails Performance tracker. Alternative to the NewRelic, Datadog or
403
406
  other services.