rails_performance 0.9.5 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +59 -9
  3. data/app/controllers/rails_performance/rails_performance_controller.rb +47 -35
  4. data/app/helpers/rails_performance/application_helper.rb +25 -7
  5. data/app/views/rails_performance/javascripts/app.js +2 -2
  6. data/app/views/rails_performance/layouts/rails_performance.html.erb +2 -2
  7. data/app/views/rails_performance/rails_performance/_summary.html.erb +1 -1
  8. data/app/views/rails_performance/rails_performance/custom.html.erb +83 -0
  9. data/app/views/rails_performance/rails_performance/delayed_job.html.erb +74 -0
  10. data/app/views/rails_performance/rails_performance/grape.html.erb +64 -0
  11. data/app/views/rails_performance/rails_performance/rake.html.erb +55 -0
  12. data/app/views/rails_performance/rails_performance/recent.html.erb +3 -1
  13. data/app/views/rails_performance/rails_performance/requests.html.erb +1 -1
  14. data/app/views/rails_performance/rails_performance/{jobs.html.erb → sidekiq.html.erb} +5 -4
  15. data/app/views/rails_performance/rails_performance/summary.js.erb +1 -1
  16. data/app/views/rails_performance/rails_performance/trace.js.erb +1 -1
  17. data/app/views/rails_performance/shared/_header.html.erb +9 -1
  18. data/app/views/rails_performance/stylesheets/style.css +5 -0
  19. data/config/routes.rb +7 -3
  20. data/lib/generators/rails_performance/install/USAGE +8 -0
  21. data/lib/generators/rails_performance/install/install_generator.rb +8 -0
  22. data/lib/generators/rails_performance/install/templates/initializer.rb +23 -0
  23. data/lib/rails_performance.rb +40 -7
  24. data/lib/rails_performance/data_source.rb +52 -13
  25. data/lib/rails_performance/engine.rb +39 -18
  26. data/lib/rails_performance/extensions/{capture_everything.rb → trace.rb} +2 -2
  27. data/lib/rails_performance/gems/custom_ext.rb +33 -0
  28. data/lib/rails_performance/gems/delayed_job_ext.rb +54 -0
  29. data/lib/rails_performance/gems/grape_ext.rb +35 -0
  30. data/lib/rails_performance/gems/rake_ext.rb +40 -0
  31. data/lib/rails_performance/gems/{sidekiq.rb → sidekiq_ext.rb} +14 -12
  32. data/lib/rails_performance/instrument/metrics_collector.rb +5 -3
  33. data/lib/rails_performance/models/base_record.rb +12 -0
  34. data/lib/rails_performance/models/custom_record.rb +48 -0
  35. data/lib/rails_performance/models/delayed_job_record.rb +62 -0
  36. data/lib/rails_performance/models/grape_record.rb +61 -0
  37. data/lib/rails_performance/models/rake_record.rb +49 -0
  38. data/lib/rails_performance/models/request_record.rb +98 -0
  39. data/lib/rails_performance/models/sidekiq_record.rb +66 -0
  40. data/lib/rails_performance/models/trace_record.rb +19 -0
  41. data/lib/rails_performance/rails/middleware.rb +42 -16
  42. data/lib/rails_performance/rails/query_builder.rb +1 -1
  43. data/lib/rails_performance/reports/breakdown_report.rb +4 -16
  44. data/lib/rails_performance/reports/crash_report.rb +4 -15
  45. data/lib/rails_performance/reports/recent_requests_report.rb +7 -44
  46. data/lib/rails_performance/reports/trace_report.rb +1 -1
  47. data/lib/rails_performance/{models → thread}/current_request.rb +9 -4
  48. data/lib/rails_performance/utils.rb +15 -29
  49. data/lib/rails_performance/version.rb +1 -1
  50. metadata +96 -10
  51. data/lib/rails_performance/models/job_record.rb +0 -48
  52. data/lib/rails_performance/models/record.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91dc41ef53b796c8c0755afd109fc7b7684ea9a5567828ab0e7f9e6c80cf9e79
4
- data.tar.gz: 434e5e19a7abb0fc86b094d591623d626ab4b8a8e2ad28b70d2dfe70583e510b
3
+ metadata.gz: d488f59068653fd127b680b6d2c067fbc23f85c84526d1259b2fb47dd3e25367
4
+ data.tar.gz: 6efcf5fb469225f298bf21b2812792acf771aebf27b623d747d4c46e29313dc3
5
5
  SHA512:
6
- metadata.gz: dffbb9eab0930f214009a8717c97a9fe82b7ea5fea22cd7a18d9a34426811d8467a19600e38e5fbdc1eb4c1aee1308b7819a8b79ff77d721907a644b9f2facea
7
- data.tar.gz: 69e08649d416bf680f203ee801534c1c5dbedd5ee956e85cca5439db3eaa8062ca830800454eb37335059732239946f6a39ad0a1d756b7efa40864fc5ebb9dc9
6
+ metadata.gz: 2513587de28e920769405e717488fe64725e780aa3f33f012e78078c7ece12afe873347c14ec450568066fbe7f2d031a3b04e164836dc3759725416ff5a95406
7
+ data.tar.gz: 87f823f42bbaf9c1491e49bbd194d8312ea395cb32372eac58fa97660b9a999c1de5106c5ab13d8ed28d63baebe6d2b8d8d05b933aece8ffaf4d5af338058417
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Rails Performance
2
2
 
3
- [![Build Status](https://travis-ci.org/igorkasyanchuk/rails_performance.svg?branch=master)](https://travis-ci.org/igorkasyanchuk/rails_performance)
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
+ [![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)
4
6
 
5
7
  A self-hosted tool to monitor the performance of your Ruby on Rails application.
6
8
 
@@ -16,14 +18,18 @@ It allows you to track:
16
18
  - total duration of time spent per request, views rendering, DB
17
19
  - SQL queries, rendering logs in "Recent Requests" section
18
20
  - simple 500-crashes reports
19
- - track Sidekiq jobs performance
20
- - works with Rails 4.2+ (and probably 4.1, 4.0 too)
21
+ - Sidekiq jobs
22
+ - Delayed Job jobs
23
+ - Grape API inside Rails app
24
+ - Rake tasks performance
25
+ - Custom events wrapped with `RailsPerformance.measure do .. end` block
26
+ - works with Rails 4.2+ (and probably 4.1, 4.0 too) and Ruby 2.2+
21
27
 
22
28
  All data are stored in `local` Redis and not sent to any 3rd party servers.
23
29
 
24
30
  ## Production
25
31
 
26
- Gem is production-ready. At least on my 2 applications with ~800 unique users per day it works perfectly.
32
+ Gem is production-ready. At least on my 2 applications with ~800 unique users per day it works perfectly.
27
33
 
28
34
  Just don't forget to protect performance dashboard with http basic auth or check of current_user.
29
35
 
@@ -49,6 +55,10 @@ RailsPerformance.setup do |config|
49
55
  config.debug = false # currently not used>
50
56
  config.enabled = true
51
57
 
58
+ # default path where to mount gem,
59
+ # alternatively you can mount the RailsPerformance::Engine in your routes.rb
60
+ config.mount_at = '/rails/performance'
61
+
52
62
  # protect your Performance Dashboard with HTTP BASIC password
53
63
  config.http_basic_authentication_enabled = false
54
64
  config.http_basic_authentication_user_name = 'rails_performance'
@@ -62,12 +72,13 @@ end if defined?(RailsPerformance)
62
72
  ```
63
73
 
64
74
  ## Installation
75
+
65
76
  Add this line to your application's Gemfile:
66
77
 
67
78
  ```ruby
68
79
  gem 'rails_performance'
69
80
 
70
- # or
81
+ # or
71
82
 
72
83
  group :development, :production do
73
84
  gem 'rails_performance'
@@ -75,18 +86,47 @@ end
75
86
  ```
76
87
 
77
88
  And then execute:
89
+
78
90
  ```bash
79
91
  $ bundle
80
92
  ```
81
93
 
94
+ Create default configuration file:
95
+
96
+ ```bash
97
+ $ rails generate rails_performance:install
98
+ ```
99
+
100
+ Have a look at `config/initializers/rails_performance.rb` and adjust the configuration to your needs.
101
+
82
102
  You must also have installed Redis server, because this gem is storing data into it.
83
103
 
84
104
  After installation and configuration, start your Rails application, make a few requests, and open `https://localhost:3000/rails/performance` URL.
85
105
 
106
+ ### Alternative: Mounting the engine yourself
107
+
108
+ 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.
109
+ You can skip the `mount_at` and `http_basic_authentication_*` configurations then, if you like.
110
+
111
+ ```ruby
112
+ # config/routes.rb
113
+ Rails.application.routes.draw do
114
+ ...
115
+ # example for usage with Devise
116
+ authenticate :user, -> (user) { user.admin? } do
117
+ mount RailsPerformance::Engine, at: 'rails/performance'
118
+ end
119
+ end
120
+ ```
121
+
122
+
123
+
86
124
  ## How it works
87
125
 
88
126
  ![Schema](docs/rails_performance.png)
89
127
 
128
+ In addition it's wrapping gems internal methods and collecting performance information. See `./lib/rails_performance/gems/*` for more information.
129
+
90
130
  ## Limitations
91
131
 
92
132
  - it doesn't track params of POST/PUT requests
@@ -121,10 +161,8 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
121
161
 
122
162
  ## TODO
123
163
 
124
- - documentation in Readme
164
+ - documentation in Readme?
125
165
  - capture stacktrace of 500 errors and show in side panel
126
- - generator for initial config
127
- - CI for tests
128
166
  - time/zone config?
129
167
  - connected charts on dashboard, when zoom, when hover?
130
168
  - ability to zoom to see requests withing specific datetime range
@@ -133,7 +171,7 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
133
171
  - better stats tooltip, do not show if nothing to show
134
172
  - dark mode toggle? save to the cookies?
135
173
  - integration with elastic search? or other?
136
- - monitor active job (sidekiq)?
174
+ - monitor active job?
137
175
  - better logo?
138
176
  - number of requests last 24 hours, hour, etc.
139
177
  - collect deprecation.rails
@@ -141,6 +179,10 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
141
179
  - show "loading banner" until jquery is loaded?
142
180
  - better UI on smaller screens? Recent requests when URL's are long? Truncate with CSS?
143
181
  - rules for highlighting durations? how many ms to show warning, alert
182
+ - elastic search
183
+ - searchkiq
184
+ - sinatra?
185
+ - tests to check what is actually stored in redis db after request
144
186
 
145
187
  ## Contributing
146
188
 
@@ -149,7 +191,15 @@ You are welcome to contribute. I've a big list of TODO.
149
191
  ## Big thanks to contributors
150
192
 
151
193
  - https://github.com/synth
194
+ - https://github.com/alagos
195
+ - https://github.com/klondaiker
196
+ - https://github.com/jules2689
197
+ - https://github.com/PedroAugustoRamalhoDuarte
198
+ - https://github.com/haffla
152
199
 
153
200
  ## License
154
201
 
155
202
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
203
+
204
+ [<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
205
+ />](https://www.railsjazz.com/)
@@ -6,28 +6,20 @@ module RailsPerformance
6
6
 
7
7
  if RailsPerformance.enabled
8
8
  def index
9
- @datasource = RP::DataSource.new(**prepare_query, type: :requests, klass: RP::Models::Record)
9
+ @datasource = RP::DataSource.new(**prepare_query, type: :requests)
10
10
  db = @datasource.db
11
11
 
12
- @throughput_report = RP::Reports::ThroughputReport.new(db)
13
- @throughput_report_data = @throughput_report.data
14
-
15
- @response_time_report = RP::Reports::ResponseTimeReport.new(db)
16
- @response_time_report_data = @response_time_report.data
12
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
13
+ @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
17
14
  end
18
15
 
19
16
  def summary
20
- @datasource = RP::DataSource.new(**prepare_query, type: :requests, klass: RP::Models::Record)
17
+ @datasource = RP::DataSource.new(**prepare_query, type: :requests)
21
18
  db = @datasource.db
22
19
 
23
- @throughput_report = RP::Reports::ThroughputReport.new(db)
24
- @throughput_report_data = @throughput_report.data
25
-
26
- @response_time_report = RP::Reports::ResponseTimeReport.new(db)
27
- @response_time_report_data = @response_time_report.data
28
-
29
- @report = RP::Reports::BreakdownReport.new(db, title: "Requests")
30
- @data = @report.data
20
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
21
+ @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
22
+ @data = RP::Reports::BreakdownReport.new(db, title: "Requests").data
31
23
 
32
24
  respond_to do |format|
33
25
  format.js {}
@@ -36,9 +28,8 @@ module RailsPerformance
36
28
  end
37
29
 
38
30
  def trace
39
- @record = RP::Models::Record.find_by(request_id: params[:id])
40
- @report = RP::Reports::TraceReport.new(request_id: params[:id])
41
- @data = @report.data
31
+ @record = RP::Models::RequestRecord.find_by(request_id: params[:id])
32
+ @data = RP::Reports::TraceReport.new(request_id: params[:id]).data
42
33
  respond_to do |format|
43
34
  format.js {}
44
35
  format.any { render plain: "Doesn't open in new window. Wait until full page load." }
@@ -46,38 +37,59 @@ module RailsPerformance
46
37
  end
47
38
 
48
39
  def crashes
49
- @datasource = RP::DataSource.new(**prepare_query({status_eq: 500}), type: :requests, klass: RP::Models::Record)
40
+ @datasource = RP::DataSource.new(**prepare_query({status_eq: 500}), type: :requests)
50
41
  db = @datasource.db
51
- @report = RP::Reports::CrashReport.new(db)
52
- @data = @report.data
42
+ @data = RP::Reports::CrashReport.new(db).data
53
43
  end
54
44
 
55
45
  def requests
56
- @datasource = RP::DataSource.new(**prepare_query, type: :requests, klass: RP::Models::Record)
46
+ @datasource = RP::DataSource.new(**prepare_query, type: :requests)
57
47
  db = @datasource.db
58
- @report = RP::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :count)
59
- @data = @report.data
48
+ @data = RP::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :count).data
60
49
  end
61
50
 
62
51
  def recent
63
- @datasource = RP::DataSource.new(**prepare_query, type: :requests, klass: RP::Models::Record)
52
+ @datasource = RP::DataSource.new(**prepare_query, type: :requests)
64
53
  db = @datasource.db
65
- @report = RP::Reports::RecentRequestsReport.new(db)
66
- @data = @report.data
54
+ @data = RP::Reports::RecentRequestsReport.new(db).data
55
+ end
56
+
57
+ def sidekiq
58
+ @datasource = RP::DataSource.new(**prepare_query, type: :sidekiq)
59
+ db = @datasource.db
60
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
61
+ @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
62
+ @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
67
63
  end
68
64
 
69
- def jobs
70
- @datasource = RP::DataSource.new(**prepare_query, type: :jobs, klass: RP::Models::JobRecord)
65
+ def delayed_job
66
+ @datasource = RP::DataSource.new(**prepare_query, type: :delayed_job)
71
67
  db = @datasource.db
68
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
69
+ @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
70
+ @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
71
+ end
72
72
 
73
- @throughput_report = RP::Reports::ThroughputReport.new(db)
74
- @throughput_report_data = @throughput_report.data
73
+ def custom
74
+ @datasource = RP::DataSource.new(**prepare_query, type: :custom)
75
+ db = @datasource.db
76
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
77
+ @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
78
+ @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
79
+ end
75
80
 
76
- @response_time_report = RP::Reports::ResponseTimeReport.new(db)
77
- @response_time_report_data = @response_time_report.data
81
+ def grape
82
+ @datasource = RP::DataSource.new(**prepare_query, type: :grape)
83
+ db = @datasource.db
84
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
85
+ @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
86
+ end
78
87
 
79
- @recent_report = RP::Reports::RecentRequestsReport.new(db)
80
- @recent_report_data = @recent_report.data(:jobs)
88
+ def rake
89
+ @datasource = RP::DataSource.new(**prepare_query, type: :rake)
90
+ db = @datasource.db
91
+ @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
92
+ @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
81
93
  end
82
94
 
83
95
  private
@@ -1,10 +1,10 @@
1
1
  module RailsPerformance
2
2
  module ApplicationHelper
3
- def round_it(value)
3
+ def round_it(value, limit = 1)
4
4
  return nil unless value
5
5
  return value if value.is_a?(Integer)
6
6
 
7
- value.nan? ? nil : value.round(1)
7
+ value.nan? ? nil : value.round(limit)
8
8
  end
9
9
 
10
10
  def duraction_alert_class(duration_str)
@@ -30,9 +30,15 @@ module RailsPerformance
30
30
  end
31
31
  end
32
32
 
33
- def ms(value)
34
- result = round_it(value)
35
- result && result != 0 ? "#{result} ms" : '-'
33
+ def mss(value, limit = 1)
34
+ ms(value.to_f * 1000, limit)
35
+ end
36
+
37
+ def ms(value, limit = 1)
38
+ result = round_it(value, limit)
39
+ return '-' if result.nil?
40
+
41
+ result && result != 0 ? "#{result} ms" : '< 0 ms'
36
42
  end
37
43
 
38
44
  def short_path(path, length: 60)
@@ -65,6 +71,8 @@ module RailsPerformance
65
71
 
66
72
  def status_tag(status)
67
73
  klass = case status.to_s
74
+ when /error/
75
+ "tag is-danger"
68
76
  when /^5/
69
77
  "tag is-danger"
70
78
  when /^4/
@@ -73,6 +81,8 @@ module RailsPerformance
73
81
  "tag is-info"
74
82
  when /^2/
75
83
  "tag is-success"
84
+ when /success/
85
+ "tag is-success"
76
86
  else
77
87
  nil
78
88
  end
@@ -108,8 +118,16 @@ module RailsPerformance
108
118
  "is-active" if controller_name == "rails_performance" && action_name == "requests"
109
119
  when :recent
110
120
  "is-active" if controller_name == "rails_performance" && action_name == "recent"
111
- when :jobs
112
- "is-active" if controller_name == "rails_performance" && action_name == "jobs"
121
+ when :sidekiq
122
+ "is-active" if controller_name == "rails_performance" && action_name == "sidekiq"
123
+ when :delayed_job
124
+ "is-active" if controller_name == "rails_performance" && action_name == "delayed_job"
125
+ when :grape
126
+ "is-active" if controller_name == "rails_performance" && action_name == "grape"
127
+ when :rake
128
+ "is-active" if controller_name == "rails_performance" && action_name == "rake"
129
+ when :custom
130
+ "is-active" if controller_name == "rails_performance" && action_name == "custom"
113
131
  end
114
132
  end
115
133
  end
@@ -22,7 +22,7 @@ function showTIRChart(div, data, addon, name) {
22
22
  },
23
23
  formatter: function() {
24
24
  if (this.y == 0) {
25
- return '';
25
+ return 'n/a';
26
26
  }
27
27
  return this.y + addon;
28
28
  }
@@ -107,7 +107,7 @@ function showRTChart(div, data) {
107
107
  },
108
108
  formatter: function() {
109
109
  if (this.y == 0) {
110
- return "";
110
+ return 'n/a';
111
111
  }
112
112
  return this.y + ' ms';
113
113
  }
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>Rails Performance</title>
7
7
  <%= csrf_meta_tags %>
8
- <%= csp_meta_tag if ::Rails::VERSION::MAJOR.to_i >= 5 %>
8
+ <%= csp_meta_tag if ::Rails::VERSION::STRING.to_f >= 5.2 %>
9
9
  <%= render '/rails_performance/stylesheets/stylesheets' %>
10
10
  <link rel="shortcut icon" href="/favicon.ico">
11
11
  </head>
@@ -29,4 +29,4 @@
29
29
  <%= yield :on_load %>
30
30
 
31
31
  </body>
32
- </html>
32
+ </html>
@@ -4,7 +4,7 @@
4
4
  <h2 class="subtitle">Average Response Time</h2>
5
5
  <div id="response_time_report_chart_mini" class="chart_mini"></div>
6
6
 
7
- <h2 class="subtitle"><%= @report.title %></h2>
7
+ <h2 class="subtitle"><%= title %></h2>
8
8
  <table class="table is-fullwidth is-hoverable is-narrow is-size-7">
9
9
  <thead>
10
10
  <tr>
@@ -0,0 +1,83 @@
1
+ <title>Custom Events</title>
2
+
3
+ <% unless @datasource.default? %>
4
+ <%#= link_to raw("&larr; Back"), rails_performance_path, class: "back_link" %>
5
+ <% end %>
6
+
7
+ <div class="card">
8
+ <div class="card-content">
9
+ <h2 class="subtitle">Recent Events (last <%= RailsPerformance::Reports::RecentRequestsReport::TIME_WINDOW / 60 %> minutes)<h2>
10
+
11
+ <table class="table is-fullwidth is-hoverable is-narrow">
12
+ <thead>
13
+ <tr>
14
+ <th data-sort="string">Datetime</th>
15
+ <th data-sort="string">Tag</th>
16
+ <th data-sort="string">Namespace</th>
17
+ <th data-sort="string">Status</th>
18
+ <th data-sort="float">Duration</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% if @recent_report_data.empty? %>
23
+ <tr>
24
+ <td colspan="5">
25
+ Nothing to show here. Try to make a few requests in the main app.
26
+
27
+ <pre>
28
+ <code>
29
+ # in controller for example
30
+ def index
31
+ RailsPerformance.measure("stats calculation", "reports#index") do
32
+ stats = User.calculate_stats
33
+ end
34
+ end
35
+ </code>
36
+ </pre>
37
+ </td>
38
+ </tr>
39
+ <% end %>
40
+ <% @recent_report_data.each do |e| %>
41
+ <tr>
42
+ <td><%= format_datetime e[:datetime] %></td>
43
+ <td><%= e[:tag_name] %></td>
44
+ <td><%= e[:namespace_name] %></td>
45
+ <td><%= status_tag e[:status] %></td>
46
+ <td class="nowrap"><%= ms e[:duration] %></td>
47
+ </tr>
48
+ <% end %>
49
+ </tbody>
50
+ </table>
51
+ </div>
52
+ </div>
53
+
54
+ <br/>
55
+
56
+ <div class="card">
57
+ <div class="card-content">
58
+ <h2 class="subtitle">Custom Events Throughput Report</h2>
59
+ <div id="throughput_report_chart" class="chart"></div>
60
+ <p class="content is-small">All custom events in the application</p>
61
+ </div>
62
+ </div>
63
+
64
+ <br/>
65
+
66
+ <div class="card">
67
+ <div class="card-content">
68
+ <h2 class="subtitle">Average Execution Time</h2>
69
+ <div id="response_time_report_chart" class="chart"></div>
70
+ <p class="content is-small">All custom events in the application</p>
71
+ </div>
72
+ </div>
73
+
74
+
75
+ <% content_for :on_load do %>
76
+ <script>
77
+ var data1 = <%= raw @throughput_report_data.to_json %>;
78
+ showTIRChart('throughput_report_chart', data1, ' events / minute', 'Events');
79
+
80
+ var data2 = <%= raw @response_time_report_data.to_json %>;
81
+ showRTChart('response_time_report_chart', data2);
82
+ </script>
83
+ <% end %>