rails_performance 1.2.2 → 1.3.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -13
  3. data/Rakefile +14 -14
  4. data/app/assets/images/download.svg +3 -0
  5. data/app/controllers/rails_performance/base_controller.rb +21 -21
  6. data/app/controllers/rails_performance/concerns/csv_exportable.rb +29 -0
  7. data/app/controllers/rails_performance/rails_performance_controller.rb +95 -49
  8. data/app/helpers/rails_performance/rails_performance_helper.rb +152 -156
  9. data/app/views/rails_performance/javascripts/app.js +2 -2
  10. data/app/views/rails_performance/rails_performance/_export.html.erb +3 -0
  11. data/app/views/rails_performance/rails_performance/crashes.html.erb +8 -1
  12. data/app/views/rails_performance/rails_performance/recent.html.erb +8 -6
  13. data/app/views/rails_performance/rails_performance/requests.html.erb +8 -1
  14. data/app/views/rails_performance/rails_performance/slow.html.erb +4 -1
  15. data/app/views/rails_performance/shared/_header.html.erb +0 -1
  16. data/app/views/rails_performance/stylesheets/style.css +6 -0
  17. data/config/routes.rb +16 -18
  18. data/lib/generators/rails_performance/install/install_generator.rb +1 -1
  19. data/lib/generators/rails_performance/install/templates/initializer.rb +56 -38
  20. data/lib/rails_performance/data_source.rb +120 -121
  21. data/lib/rails_performance/engine.rb +8 -8
  22. data/lib/rails_performance/extensions/trace.rb +32 -33
  23. data/lib/rails_performance/gems/custom_ext.rb +31 -34
  24. data/lib/rails_performance/gems/delayed_job_ext.rb +50 -54
  25. data/lib/rails_performance/gems/grape_ext.rb +33 -35
  26. data/lib/rails_performance/gems/rake_ext.rb +41 -44
  27. data/lib/rails_performance/gems/sidekiq_ext.rb +34 -37
  28. data/lib/rails_performance/instrument/metrics_collector.rb +50 -49
  29. data/lib/rails_performance/models/base_record.rb +33 -36
  30. data/lib/rails_performance/models/collection.rb +35 -36
  31. data/lib/rails_performance/models/custom_record.rb +47 -48
  32. data/lib/rails_performance/models/delayed_job_record.rb +61 -62
  33. data/lib/rails_performance/models/grape_record.rb +60 -61
  34. data/lib/rails_performance/models/rake_record.rb +48 -49
  35. data/lib/rails_performance/models/request_record.rb +123 -120
  36. data/lib/rails_performance/models/sidekiq_record.rb +65 -66
  37. data/lib/rails_performance/models/trace_record.rb +18 -19
  38. data/lib/rails_performance/rails/middleware.rb +75 -76
  39. data/lib/rails_performance/rails/query_builder.rb +18 -20
  40. data/lib/rails_performance/reports/base_report.rb +60 -60
  41. data/lib/rails_performance/reports/breakdown_report.rb +15 -18
  42. data/lib/rails_performance/reports/crash_report.rb +15 -17
  43. data/lib/rails_performance/reports/recent_requests_report.rb +24 -24
  44. data/lib/rails_performance/reports/requests_report.rb +27 -27
  45. data/lib/rails_performance/reports/response_time_report.rb +17 -17
  46. data/lib/rails_performance/reports/slow_requests_report.rb +4 -4
  47. data/lib/rails_performance/reports/throughput_report.rb +15 -17
  48. data/lib/rails_performance/reports/trace_report.rb +16 -18
  49. data/lib/rails_performance/thread/current_request.rb +33 -34
  50. data/lib/rails_performance/utils.rb +53 -54
  51. data/lib/rails_performance/version.rb +2 -2
  52. data/lib/rails_performance.rb +38 -33
  53. metadata +20 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb7e94d5d6bb24923c0b13fce9d05c1bec53f2cb07305405852ca3803cee9f25
4
- data.tar.gz: 162d27d3c200f077fa378bc6a83a11e13a4e3891b1b9104fde5a62f123cc7fff
3
+ metadata.gz: eb51d8480c3184c5dba0f1eb8ac6de2947d22dd9afa5aa2434a9ccf26704e71b
4
+ data.tar.gz: ea76f7ca185e5e531aaa5b936cc22fb60fb9319601b62773c3f6e9b6915287b9
5
5
  SHA512:
6
- metadata.gz: 1b87d9850d195628f6765cf7ac18223a5ded9705f7d1d0df66ea70cd83f0669f8c24759e3ca499aad1c9d99786095492731cd86f575bbe1571bf99edeaa41a0b
7
- data.tar.gz: c601d675b34ae16baa725630e22c7c9473d17851a694ea3ecffdea6ee59bd41eed2a816fcda051cd5baf5d40ced7054591260f0b0bfb6eb340de79fcf2a65895
6
+ metadata.gz: cf34b64cb3c9d55faeff3820f09f6f91a1a8d59138e4a4c4ad0f172c0c7489f1dd5307ad90a447013b8a317616c0d647c618831ca63ddea7cfbe0758c2002510
7
+ data.tar.gz: 6aaf94e150feb3aa16e7c18f7c2195c85af4aee035bffef2e9d48f5dd164e1ff45d3c2d5ea32b5395c1a8f23efef524ff4ecb6bc069922d7631e65fb785f93df
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![Tests](https://github.com/igorkasyanchuk/rails_performance/actions/workflows/ruby.yml/badge.svg)](https://github.com/igorkasyanchuk/rails_performance/actions/workflows/ruby.yml)
4
4
  [![RailsJazz](https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/my_other.svg?raw=true)](https://www.railsjazz.com)
5
- [![https://www.patreon.com/igorkasyanchuk](https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/patron.svg?raw=true)](https://www.patreon.com/igorkasyanchuk)
6
5
  [![Listed on OpenSource-Heroes.com](https://opensource-heroes.com/badge-v1.svg)](https://opensource-heroes.com/r/igorkasyanchuk/rails_performance)
7
6
 
8
7
  A self-hosted tool to monitor the performance of your Ruby on Rails application.
@@ -52,7 +51,7 @@ Create `config/initializers/rails_performance.rb` in your app:
52
51
 
53
52
  ```ruby
54
53
  RailsPerformance.setup do |config|
55
- config.redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new)
54
+ config.redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new(url: ENV["REDIS_URL"].presence || "redis://127.0.0.1:6379/0"))
56
55
  config.duration = 4.hours
57
56
 
58
57
  config.debug = false # currently not used>
@@ -81,6 +80,13 @@ RailsPerformance.setup do |config|
81
80
  # for example when you have `current_user`
82
81
  # config.verify_access_proc = proc { |controller| controller.current_user && controller.current_user.admin? }
83
82
 
83
+ # You can ignore endpoints with Rails standard notation controller#action
84
+ # config.ignored_endpoints = ['HomeController#contact']
85
+
86
+ # You can ignore request paths by specifying the beginning of the path.
87
+ # For example, all routes starting with '/admin' can be ignored:
88
+ config.ignored_paths = ['/rails/performance', '/admin']
89
+
84
90
  # store custom data for the request
85
91
  # config.custom_data_proc = proc do |env|
86
92
  # request = Rack::Request.new(env)
@@ -238,17 +244,9 @@ If "schema" how records are stored i Redis is changed, and this is a breaking ch
238
244
 
239
245
  ## Big thanks to contributors
240
246
 
241
- - https://github.com/synth
242
- - https://github.com/alagos
243
- - https://github.com/klondaiker
244
- - https://github.com/jules2689
245
- - https://github.com/PedroAugustoRamalhoDuarte
246
- - https://github.com/haffla
247
- - https://github.com/D1ceWard
248
- - https://github.com/carl-printreleaf
249
- - https://github.com/langalex
250
- - https://github.com/olleolleolle
251
- - https://github.com/desheikh
247
+ https://github.com/igorkasyanchuk/rails_performance/graphs/contributors
248
+
249
+ ## Other
252
250
 
253
251
  [<img src="https://opensource-heroes.com/svg/embed/igorkasyanchuk/rails_performance"
254
252
  />](https://opensource-heroes.com/r/igorkasyanchuk/rails_performance)
data/Rakefile CHANGED
@@ -1,31 +1,31 @@
1
1
  begin
2
- require 'bundler/setup'
2
+ require "bundler/setup"
3
3
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
5
  end
6
6
 
7
- require 'rdoc/task'
7
+ require "rdoc/task"
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'RailsPerformance'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.md')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "RailsPerformance"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.md")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
15
  end
16
16
 
17
17
  APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
- load 'rails/tasks/engine.rake'
18
+ load "rails/tasks/engine.rake"
19
19
 
20
- load 'rails/tasks/statistics.rake'
20
+ load "rails/tasks/statistics.rake"
21
21
 
22
- require 'bundler/gem_tasks'
22
+ require "bundler/gem_tasks"
23
23
 
24
- require 'rake/testtask'
24
+ require "rake/testtask"
25
25
 
26
26
  Rake::TestTask.new(:test) do |t|
27
- t.libs << 'test'
28
- t.pattern = 'test/**/*_test.rb'
27
+ t.libs << "test"
28
+ t.pattern = "test/**/*_test.rb"
29
29
  t.verbose = false
30
30
  end
31
31
 
@@ -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="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
3
+ </svg>
@@ -1,21 +1,21 @@
1
- module RailsPerformance
2
- class BaseController < ActionController::Base
3
- layout 'rails_performance/layouts/rails_performance'
4
-
5
- before_action :verify_access
6
-
7
- if RailsPerformance.http_basic_authentication_enabled
8
- http_basic_authenticate_with \
9
- name: RailsPerformance.http_basic_authentication_user_name,
10
- password: RailsPerformance.http_basic_authentication_password
11
- end
12
-
13
- private
14
-
15
- def verify_access
16
- result = RailsPerformance.verify_access_proc.call(self)
17
- redirect_to('/', error: 'Access Denied', status: 401) unless result
18
- end
19
-
20
- end
21
- end
1
+ module RailsPerformance
2
+ class BaseController < ActionController::Base
3
+ include RailsPerformance::Concerns::CsvExportable
4
+ layout "rails_performance/layouts/rails_performance"
5
+
6
+ before_action :verify_access
7
+
8
+ if RailsPerformance.http_basic_authentication_enabled
9
+ http_basic_authenticate_with \
10
+ name: RailsPerformance.http_basic_authentication_user_name,
11
+ password: RailsPerformance.http_basic_authentication_password
12
+ end
13
+
14
+ private
15
+
16
+ def verify_access
17
+ result = RailsPerformance.verify_access_proc.call(self)
18
+ redirect_to("/", error: "Access Denied", status: 401) unless result
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ require "csv"
2
+ module RailsPerformance
3
+ module Concerns
4
+ module CsvExportable
5
+ extend ActiveSupport::Concern
6
+
7
+ def export_to_csv(filename, data)
8
+ return if data.blank?
9
+
10
+ send_data generate_csv(data),
11
+ filename: "#{filename}_#{Time.zone.today}.csv",
12
+ type: "text/csv",
13
+ disposition: "attachment"
14
+ end
15
+
16
+ private
17
+
18
+ def generate_csv(data)
19
+ CSV.generate(headers: true) do |csv|
20
+ headers = data.first.keys
21
+ csv << headers.map(&:to_s)
22
+ data.each do |entry|
23
+ csv << headers.map { |header| entry[header].to_s }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,58 +1,84 @@
1
- require_relative './base_controller.rb'
1
+ require_relative "base_controller"
2
2
 
3
3
  module RailsPerformance
4
4
  class RailsPerformanceController < RailsPerformance::BaseController
5
-
6
5
  protect_from_forgery except: :recent
7
6
 
8
7
  if RailsPerformance.enabled
9
8
  def index
10
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
11
- db = @datasource.db
9
+ @datasource = RailsPerformance::DataSource.new(
10
+ **prepare_query, type: :requests
11
+ )
12
+ db = @datasource.db
12
13
 
13
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
14
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
14
15
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
15
16
  end
16
17
 
17
18
  def summary
18
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
19
- db = @datasource.db
19
+ @datasource = RailsPerformance::DataSource.new(
20
+ **prepare_query, type: :requests
21
+ )
22
+ db = @datasource.db
20
23
 
21
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
24
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
22
25
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
23
- @data = RailsPerformance::Reports::BreakdownReport.new(db, title: "Requests").data
24
-
26
+ @data = RailsPerformance::Reports::BreakdownReport.new(
27
+ db, title: "Requests"
28
+ ).data
25
29
  respond_to do |format|
26
30
  format.js {}
27
- format.any { render plain: "Doesn't open in new window. Wait until full page load." }
31
+ format.any do
32
+ render plain: "Doesn't open in new window. Wait until full page load."
33
+ end
28
34
  end
29
35
  end
30
36
 
31
37
  def trace
32
38
  @record = RailsPerformance::Models::RequestRecord.find_by(request_id: params[:id])
33
- @data = RailsPerformance::Reports::TraceReport.new(request_id: params[:id]).data
39
+ @data = RailsPerformance::Reports::TraceReport.new(request_id: params[:id]).data
34
40
  respond_to do |format|
35
41
  format.js {}
36
- format.any { render plain: "Doesn't open in new window. Wait until full page load." }
42
+ format.any do
43
+ render plain: "Doesn't open in new window. Wait until full page load."
44
+ end
37
45
  end
38
46
  end
39
47
 
40
48
  def crashes
41
- @datasource = RailsPerformance::DataSource.new(**prepare_query({status_eq: 500}), type: :requests)
42
- db = @datasource.db
43
- @data = RailsPerformance::Reports::CrashReport.new(db).data
49
+ @datasource = RailsPerformance::DataSource.new(
50
+ **prepare_query({status_eq: 500}), type: :requests
51
+ )
52
+ db = @datasource.db
53
+ @data = RailsPerformance::Reports::CrashReport.new(db).data
54
+
55
+ respond_to do |format|
56
+ format.html
57
+ format.csv do
58
+ export_to_csv "error_report", @data
59
+ end
60
+ end
44
61
  end
45
62
 
46
63
  def requests
47
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
48
- db = @datasource.db
49
- @data = RailsPerformance::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :count).data
64
+ @datasource = RailsPerformance::DataSource.new(**prepare_query,
65
+ type: :requests)
66
+ db = @datasource.db
67
+ @data = RailsPerformance::Reports::RequestsReport.new(db,
68
+ group: :controller_action_format, sort: :count).data
69
+ respond_to do |format|
70
+ format.html
71
+ format.csv do
72
+ export_to_csv "requests_report", @data
73
+ end
74
+ end
50
75
  end
51
76
 
52
77
  def recent
53
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
54
- db = @datasource.db
55
- @data = RailsPerformance::Reports::RecentRequestsReport.new(db).data(params[:from_timei])
78
+ @datasource = RailsPerformance::DataSource.new(**prepare_query,
79
+ type: :requests)
80
+ db = @datasource.db
81
+ @data = RailsPerformance::Reports::RecentRequestsReport.new(db).data(params[:from_timei])
56
82
 
57
83
  # example
58
84
  # :controller=>"HomeController",
@@ -73,54 +99,75 @@ module RailsPerformance
73
99
  # "email"=>nil,
74
100
  # "user_agent"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}]
75
101
 
76
- respond_to do |page|
77
- page.html
78
- page.js
102
+ respond_to do |format|
103
+ format.html
104
+ format.js
105
+ format.csv do
106
+ export_to_csv "recent_requests_report", @data
107
+ end
79
108
  end
80
109
  end
81
110
 
82
111
  def slow
83
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
84
- db = @datasource.db
85
- @data = RailsPerformance::Reports::SlowRequestsReport.new(db).data
112
+ @datasource = RailsPerformance::DataSource.new(**prepare_query,
113
+ type: :requests)
114
+ db = @datasource.db
115
+ @data = RailsPerformance::Reports::SlowRequestsReport.new(db).data
116
+
117
+ respond_to do |format|
118
+ format.html
119
+ format.csv do
120
+ export_to_csv "slow_requests_report", @data
121
+ end
122
+ end
86
123
  end
87
124
 
88
125
  def sidekiq
89
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :sidekiq)
90
- db = @datasource.db
91
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
126
+ @datasource = RailsPerformance::DataSource.new(
127
+ **prepare_query, type: :sidekiq
128
+ )
129
+ db = @datasource.db
130
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
92
131
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
93
- @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
132
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
94
133
  end
95
134
 
96
135
  def delayed_job
97
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :delayed_job)
98
- db = @datasource.db
99
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
136
+ @datasource = RailsPerformance::DataSource.new(
137
+ **prepare_query, type: :delayed_job
138
+ )
139
+ db = @datasource.db
140
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
100
141
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
101
- @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
142
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
102
143
  end
103
144
 
104
145
  def custom
105
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :custom)
106
- db = @datasource.db
107
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
146
+ @datasource = RailsPerformance::DataSource.new(
147
+ **prepare_query, type: :custom
148
+ )
149
+ db = @datasource.db
150
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
108
151
  @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
109
- @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
152
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
110
153
  end
111
154
 
112
155
  def grape
113
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :grape)
114
- db = @datasource.db
115
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
116
- @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
156
+ @datasource = RailsPerformance::DataSource.new(
157
+ **prepare_query, type: :grape
158
+ )
159
+ db = @datasource.db
160
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
161
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
117
162
  end
118
163
 
119
164
  def rake
120
- @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :rake)
121
- db = @datasource.db
122
- @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
123
- @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
165
+ @datasource = RailsPerformance::DataSource.new(
166
+ **prepare_query, type: :rake
167
+ )
168
+ db = @datasource.db
169
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
170
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
124
171
  end
125
172
 
126
173
  private
@@ -129,6 +176,5 @@ module RailsPerformance
129
176
  RailsPerformance::Rails::QueryBuilder.compose_from(query)
130
177
  end
131
178
  end
132
-
133
179
  end
134
180
  end