rails_performance 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb51d8480c3184c5dba0f1eb8ac6de2947d22dd9afa5aa2434a9ccf26704e71b
4
- data.tar.gz: ea76f7ca185e5e531aaa5b936cc22fb60fb9319601b62773c3f6e9b6915287b9
3
+ metadata.gz: ce8db107a23bdd7c902fa8edcc2ebe260998e1cf7712f0a710131983b28c3fa9
4
+ data.tar.gz: 82e818c24db06fb74d6d477aba06f0841174894c23f45fab785dd6dd0f808aa8
5
5
  SHA512:
6
- metadata.gz: cf34b64cb3c9d55faeff3820f09f6f91a1a8d59138e4a4c4ad0f172c0c7489f1dd5307ad90a447013b8a317616c0d647c618831ca63ddea7cfbe0758c2002510
7
- data.tar.gz: 6aaf94e150feb3aa16e7c18f7c2195c85af4aee035bffef2e9d48f5dd164e1ff45d3c2d5ea32b5395c1a8f23efef524ff4ecb6bc069922d7631e65fb785f93df
6
+ metadata.gz: 49d48df321943a17cd226f68ace96bbebca96ab6b47dde70e6cc95fd21276338562d3e0dbe365d1133aa6cd93981d2dd0980790cac8f52512ac2fbdb3558263d
7
+ data.tar.gz: 6c3ec9d24045abc760cba57d2f3d12fe6c3ea0e35a49a138bad3bfec06ae9c8a0ebc11721c5a3c92a9f3dcad6dc80ac98d1b0d6e3fd0a2a8063b11a715dfb5e8
@@ -13,6 +13,7 @@ module RailsPerformance
13
13
 
14
14
  @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
15
15
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
16
+ @percentile_report_data = RailsPerformance::Reports::PercentileReport.new(db).data
16
17
  end
17
18
 
18
19
  def summary
@@ -9,24 +9,36 @@
9
9
  <%= render '/rails_performance/stylesheets/stylesheets' %>
10
10
  <link rel="shortcut icon" href="/favicon.ico">
11
11
  </head>
12
- <body>
12
+
13
+ <body class="has-sticky-footer">
13
14
  <div class="loader-wrapper">
14
15
  <div class="loader is-loading"></div>
15
16
  </div>
16
- <section class="section">
17
- <div class="container is-fluid is-size-7">
18
- <%= render '/rails_performance/shared/header' %>
19
- <%= yield %>
20
- <div class="footer-box">
21
- © Rails Performance <span class='red'><i class="fas fa-heart"></i></span> <%= link_to 'https://github.com/igorkasyanchuk/rails_performance', 'https://github.com/igorkasyanchuk/rails_performance', target: '_blank' %>
22
- <div class="is-pulled-right">v.<%= RailsPerformance::VERSION %></div>
17
+
18
+ <div class="main-content">
19
+ <section class="section">
20
+ <div class="container is-fluid is-size-7">
21
+ <%= render '/rails_performance/shared/header' %>
22
+ <%= yield %>
23
23
  </div>
24
+ </section>
25
+ </div>
26
+
27
+ <footer class="footer footer-box">
28
+ <div class="container is-fluid is-size-7">
29
+ © Rails Performance <span class='red'><i class="fas fa-heart"></i></span>
30
+ <%= link_to 'https://github.com/igorkasyanchuk/rails_performance', 'https://github.com/igorkasyanchuk/rails_performance', target: '_blank' %>
31
+ <div class="is-pulled-right">v.<%= RailsPerformance::VERSION %></div>
24
32
  </div>
25
- </section>
33
+ </footer>
34
+
26
35
  <%= render '/rails_performance/panel' %>
27
- <div class="panel-overlay">
36
+
37
+ <div class="panel-overlay"></div>
38
+
28
39
  <%= render '/rails_performance/javascripts/javascripts' %>
29
- <%= yield :on_load %>
30
40
 
41
+ <%= yield :on_load %>
31
42
  </body>
43
+
32
44
  </html>
@@ -4,6 +4,35 @@
4
4
  <%#= link_to raw("&larr; Back"), rails_performance_path, class: "back_link" %>
5
5
  <% end %>
6
6
 
7
+ <div class="columns">
8
+ <div class="column">
9
+ <div class="card">
10
+ <div class="card-content">
11
+ <h2 class="subtitle is-size-1"><%= ms @percentile_report_data[:p50] %></h2>
12
+ <p class="content is-size-4">p50</p>
13
+ </div>
14
+ </div>
15
+ </div>
16
+
17
+ <div class="column">
18
+ <div class="card">
19
+ <div class="card-content">
20
+ <h2 class="subtitle is-size-1"><%= ms @percentile_report_data[:p95] %></h2>
21
+ <p class="content is-size-4">p95</p>
22
+ </div>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="column">
27
+ <div class="card">
28
+ <div class="card-content">
29
+ <h2 class="subtitle is-size-1"><%= ms @percentile_report_data[:p99] %></h2>
30
+ <p class="content is-size-4">p99</p>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+
7
36
  <div class="card">
8
37
  <div class="card-content">
9
38
  <h2 class="subtitle">Throughput Report</h2>
@@ -2,16 +2,17 @@
2
2
  <div class="card-content">
3
3
  <div class="columns is-vcentered">
4
4
  <div class="column">
5
- <h2 class="subtitle">Requests (path, total number, average response time)</h2>
5
+ <h2 class="subtitle">Requests Analysis</h2>
6
6
  </div>
7
7
  <div class="column is-narrow">
8
- <%= render "export" %>
8
+ <%= render "export" %>
9
9
  </div>
10
10
  </div>
11
- <table class="table is-fullwidth is-hoverable is-narrow">
11
+ <table class="table is-fullwidth is-hoverable">
12
12
  <thead>
13
13
  <tr>
14
14
  <th colspan='3'>Name</th>
15
+ <th colspan='3' class="attention">Percentile</th>
15
16
  <th colspan='3'>Average</th>
16
17
  <th colspan='3'>Slowest</th>
17
18
  </tr>
@@ -19,6 +20,9 @@
19
20
  <th data-sort="string">Controller#action</th>
20
21
  <th data-sort="string">Format</th>
21
22
  <th data-sort="int">Requests</th>
23
+ <th data-sort="float" class="attention">P50</th>
24
+ <th data-sort="float" class="attention">P95</th>
25
+ <th data-sort="float" class="attention">P99</th>
22
26
  <th data-sort="float">Duration</th>
23
27
  <th data-sort="float">Views</th>
24
28
  <th data-sort="float">DB</th>
@@ -35,6 +39,9 @@
35
39
  <td><%= link_to groups[0], rails_performance.rails_performance_summary_path({controller_eq: c, action_eq: a}), remote: true %></td>
36
40
  <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>
37
41
  <td><%= e[:count] %></td>
42
+ <td class="nowrap attention"><%= ms e[:p50_duration] %></td>
43
+ <td class="nowrap attention"><%= ms e[:p95_duration] %></td>
44
+ <td class="nowrap attention"><%= ms e[:p99_duration] %></td>
38
45
  <td class="nowrap"><%= ms e[:duration_average] %></td>
39
46
  <td class="nowrap"><%= ms e[:view_runtime_average] %></td>
40
47
  <td class="nowrap"><%= ms e[:db_runtime_average] %></td>
@@ -1,5 +1,5 @@
1
1
  <% if @record %>
2
- window.panel.header.html(window.panel.close + "<%= j report_name(@record.record_hash) %>");
2
+ window.panel.header.html(window.panel.close + "<%= j report_name(@record.record_hash.with_indifferent_access.except(*RailsPerformance.ignore_trace_headers)) %>");
3
3
  <% else %>
4
4
  window.panel.header.html(window.panel.close);
5
5
  <% end %>
@@ -16,9 +16,9 @@
16
16
  <div class="navbar-start">
17
17
  <%= link_to 'Dashboard', rails_performance.rails_performance_url, class: "navbar-item #{active?(:dashboard)}" %>
18
18
  <%= link_to 'Requests Analysis', rails_performance.rails_performance_requests_url, class: "navbar-item #{active?(:requests)}" %>
19
- <%= link_to '500 Errors', rails_performance.rails_performance_crashes_url, class: "navbar-item #{active?(:crashes)}" %>
20
19
  <%= link_to 'Recent Requests', rails_performance.rails_performance_recent_url, class: "navbar-item #{active?(:recent)}" %>
21
20
  <%= link_to 'Slow Requests', rails_performance.rails_performance_slow_url, class: "navbar-item #{active?(:slow)}" %>
21
+ <%= link_to '500 Errors', rails_performance.rails_performance_crashes_url, class: "navbar-item #{active?(:crashes)}" %>
22
22
  <% if defined?(Sidekiq) %>
23
23
  <%= link_to 'Sidekiq', rails_performance.rails_performance_sidekiq_url, class: "navbar-item #{active?(:sidekiq)}" %>
24
24
  <% end %>
@@ -72,11 +72,11 @@
72
72
  }
73
73
 
74
74
  .chart {
75
- height: 245px;
75
+ height: 300px;
76
76
  }
77
77
 
78
78
  .chart_mini {
79
- height: 150px;
79
+ height: 200px;
80
80
  width: 720px;
81
81
  }
82
82
 
@@ -121,3 +121,22 @@ table th[data-sort] {
121
121
  font-size: 7px !important;
122
122
  line-height: 20px !important;
123
123
  }
124
+
125
+ .attention {
126
+ background-color: #f6f5f5;
127
+ }
128
+
129
+ body.has-sticky-footer {
130
+ display: flex;
131
+ min-height: 100vh;
132
+ flex-direction: column;
133
+ }
134
+
135
+ .main-content {
136
+ flex: 1;
137
+ }
138
+
139
+ .footer-box {
140
+ background-color: #f5f5f5;
141
+ padding: 1rem 0;
142
+ }
@@ -30,6 +30,8 @@ module RailsPerformance
30
30
  def self.from_db(key, value)
31
31
  items = key.split("|")
32
32
 
33
+ parsed_value = JSON.parse(value) rescue {}
34
+
33
35
  RequestRecord.new(
34
36
  controller: items[2],
35
37
  action: items[4],
@@ -40,7 +42,10 @@ module RailsPerformance
40
42
  method: items[14],
41
43
  path: items[16],
42
44
  request_id: items[18],
43
- json: value
45
+ json: value,
46
+ duration: parsed_value["duration"],
47
+ view_runtime: parsed_value["view_runtime"],
48
+ db_runtime: parsed_value["db_runtime"],
44
49
  )
45
50
  end
46
51
 
@@ -12,15 +12,15 @@ module RailsPerformance
12
12
  set_defaults
13
13
  end
14
14
 
15
+ def set_defaults
16
+ end
17
+
15
18
  def collect
16
19
  db.group_by(group).each_with_object([]) do |(k, v), res|
17
20
  res << yield(k, v)
18
21
  end
19
22
  end
20
23
 
21
- def set_defaults
22
- end
23
-
24
24
  def self.time_in_app_time_zone(time)
25
25
  app_time_zone = ::Rails.application.config.time_zone
26
26
  if app_time_zone.present?
@@ -0,0 +1,14 @@
1
+ module RailsPerformance
2
+ module Reports
3
+ class PercentileReport < BaseReport
4
+ def data
5
+ durations = db.data.collect(&:duration)
6
+ {
7
+ p50: RailsPerformance::Utils.percentile(durations, 50),
8
+ p95: RailsPerformance::Utils.percentile(durations, 95),
9
+ p99: RailsPerformance::Utils.percentile(durations, 99)
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -18,7 +18,10 @@ module RailsPerformance
18
18
  db_runtime_average: db_runtimes.sum.to_f / db_runtimes.size,
19
19
  duration_slowest: durations.max,
20
20
  view_runtime_slowest: view_runtimes.max,
21
- db_runtime_slowest: db_runtimes.max
21
+ db_runtime_slowest: db_runtimes.max,
22
+ p50_duration: RailsPerformance::Utils.percentile(durations, 50),
23
+ p95_duration: RailsPerformance::Utils.percentile(durations, 95),
24
+ p99_duration: RailsPerformance::Utils.percentile(durations, 99),
22
25
  }
23
26
  end.sort_by { |e| -e[sort].to_f } # to_f because could ne NaN or nil
24
27
  end
@@ -49,5 +49,16 @@ module RailsPerformance
49
49
  sorted[center]
50
50
  end
51
51
  end
52
+
53
+ def self.percentile(values, percentile)
54
+ return nil if values.empty?
55
+
56
+ sorted = values.sort
57
+ rank = (percentile.to_f / 100) * (sorted.size - 1)
58
+
59
+ lower = sorted[rank.floor]
60
+ upper = sorted[rank.ceil]
61
+ lower + (upper - lower) * (rank - rank.floor)
62
+ end
52
63
  end
53
64
  end
@@ -1,4 +1,4 @@
1
1
  module RailsPerformance
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.2"
3
3
  SCHEMA = "1.0.1"
4
4
  end
@@ -1,5 +1,4 @@
1
1
  require "redis"
2
- require "redis-namespace"
3
2
  require "browser"
4
3
  require "active_support/core_ext/integer"
5
4
  require_relative "rails_performance/version"
@@ -24,6 +23,7 @@ require_relative "rails_performance/reports/recent_requests_report"
24
23
  require_relative "rails_performance/reports/slow_requests_report"
25
24
  require_relative "rails_performance/reports/breakdown_report"
26
25
  require_relative "rails_performance/reports/trace_report"
26
+ require_relative "rails_performance/reports/percentile_report"
27
27
  require_relative "rails_performance/extensions/trace"
28
28
  require_relative "rails_performance/thread/current_request"
29
29
 
@@ -31,7 +31,7 @@ module RailsPerformance
31
31
  FORMAT = "%Y%m%dT%H%M"
32
32
 
33
33
  mattr_accessor :redis
34
- @@redis = Redis::Namespace.new("{#{::Rails.env}-rails-performance}", redis: Redis.new)
34
+ @@redis = Redis.new
35
35
 
36
36
  mattr_accessor :duration
37
37
  @@duration = 4.hours
@@ -113,6 +113,10 @@ module RailsPerformance
113
113
  mattr_accessor :include_custom_events
114
114
  @@include_custom_events = true
115
115
 
116
+ # Trace details view configuration
117
+ mattr_accessor :ignore_trace_headers
118
+ @@ignore_trace_headers = ["datetimei"]
119
+
116
120
  def self.setup
117
121
  yield(self)
118
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-02 00:00:00.000000000 Z
11
+ date: 2024-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: redis-namespace
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: browser
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -351,6 +337,7 @@ files:
351
337
  - lib/rails_performance/reports/base_report.rb
352
338
  - lib/rails_performance/reports/breakdown_report.rb
353
339
  - lib/rails_performance/reports/crash_report.rb
340
+ - lib/rails_performance/reports/percentile_report.rb
354
341
  - lib/rails_performance/reports/recent_requests_report.rb
355
342
  - lib/rails_performance/reports/requests_report.rb
356
343
  - lib/rails_performance/reports/response_time_report.rb
@@ -379,7 +366,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
379
366
  - !ruby/object:Gem::Version
380
367
  version: '0'
381
368
  requirements: []
382
- rubygems_version: 3.5.16
369
+ rubygems_version: 3.3.7
383
370
  signing_key:
384
371
  specification_version: 4
385
372
  summary: Simple Rails Performance tracker. Alternative to the NewRelic, Datadog or