rails_performance 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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