rails_performance 0.9.6 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -8
  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/rails_performance/_summary.html.erb +1 -1
  7. data/app/views/rails_performance/rails_performance/custom.html.erb +83 -0
  8. data/app/views/rails_performance/rails_performance/delayed_job.html.erb +74 -0
  9. data/app/views/rails_performance/rails_performance/grape.html.erb +64 -0
  10. data/app/views/rails_performance/rails_performance/rake.html.erb +55 -0
  11. data/app/views/rails_performance/rails_performance/recent.html.erb +3 -1
  12. data/app/views/rails_performance/rails_performance/{jobs.html.erb → sidekiq.html.erb} +5 -4
  13. data/app/views/rails_performance/rails_performance/summary.js.erb +1 -1
  14. data/app/views/rails_performance/rails_performance/trace.js.erb +1 -1
  15. data/app/views/rails_performance/shared/_header.html.erb +9 -1
  16. data/app/views/rails_performance/stylesheets/style.css +5 -0
  17. data/config/routes.rb +5 -1
  18. data/lib/generators/rails_performance/install/USAGE +8 -0
  19. data/lib/generators/rails_performance/install/install_generator.rb +8 -0
  20. data/lib/generators/rails_performance/install/templates/initializer.rb +23 -0
  21. data/lib/rails_performance.rb +36 -7
  22. data/lib/rails_performance/data_source.rb +52 -13
  23. data/lib/rails_performance/engine.rb +39 -18
  24. data/lib/rails_performance/extensions/{capture_everything.rb → trace.rb} +2 -2
  25. data/lib/rails_performance/gems/custom_ext.rb +33 -0
  26. data/lib/rails_performance/gems/delayed_job_ext.rb +54 -0
  27. data/lib/rails_performance/gems/grape_ext.rb +35 -0
  28. data/lib/rails_performance/gems/rake_ext.rb +40 -0
  29. data/lib/rails_performance/gems/{sidekiq.rb → sidekiq_ext.rb} +14 -12
  30. data/lib/rails_performance/instrument/metrics_collector.rb +5 -3
  31. data/lib/rails_performance/models/base_record.rb +12 -0
  32. data/lib/rails_performance/models/custom_record.rb +48 -0
  33. data/lib/rails_performance/models/delayed_job_record.rb +62 -0
  34. data/lib/rails_performance/models/grape_record.rb +61 -0
  35. data/lib/rails_performance/models/rake_record.rb +49 -0
  36. data/lib/rails_performance/models/request_record.rb +98 -0
  37. data/lib/rails_performance/models/sidekiq_record.rb +66 -0
  38. data/lib/rails_performance/models/trace_record.rb +19 -0
  39. data/lib/rails_performance/rails/middleware.rb +42 -16
  40. data/lib/rails_performance/rails/query_builder.rb +1 -1
  41. data/lib/rails_performance/reports/breakdown_report.rb +4 -16
  42. data/lib/rails_performance/reports/crash_report.rb +4 -15
  43. data/lib/rails_performance/reports/recent_requests_report.rb +7 -44
  44. data/lib/rails_performance/reports/trace_report.rb +1 -1
  45. data/lib/rails_performance/{models → thread}/current_request.rb +9 -4
  46. data/lib/rails_performance/utils.rb +15 -29
  47. data/lib/rails_performance/version.rb +2 -1
  48. metadata +97 -11
  49. data/lib/rails_performance/models/job_record.rb +0 -48
  50. data/lib/rails_performance/models/record.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7057afb1ba78e88e9c7cd43609f5b42592be9a63aea28038389634afe8c6563
4
- data.tar.gz: 469e0a13402fbaff70387902b28d4d0a7441d42403df6f3bd4f89aa8a3124bf3
3
+ metadata.gz: 136a862da6c0d5b7d7d458e6c5389314cfe776d0437272d319d89a95eeaa8a11
4
+ data.tar.gz: 913394396bb6d45c8a9d12d8b2f115bc135cf9fe61eee19c79a3a88165c50551
5
5
  SHA512:
6
- metadata.gz: b1f93f46640ef509be5ea38f624f916689fe5f61bb3413428673c1ca14d41f30bdfc22111e97f0e5b0629e4421e68400cb75437d65dc3616c9fef55af7f521fb
7
- data.tar.gz: 539bb052282c277077f68b37230ae121b84d4eb7a5a87cb679a38ce03d7bc4df7fc8b38cd1f72f8f235819c53edacb24b256ca18be2e2e51bd9b282e5895faaf
6
+ metadata.gz: 4e07938ad437c12dfc911ca66d06717eded983694436b9936bc038876c685bcd9bc432c42ddc35279eb96e5511220781d790f3322f1f1acd6cfce4cce1fc27c2
7
+ data.tar.gz: 6fd601401eba7c250a31481df0f4bf1bf92c5d856ea9f5c454f3eefd45fbccc669fb1f088538a2a56a0a0decf5627eb87b2e1e93557b0515fd34ee0b575608df
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
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
20
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,7 +55,8 @@ RailsPerformance.setup do |config|
49
55
  config.debug = false # currently not used>
50
56
  config.enabled = true
51
57
 
52
- # default path where to mount gem
58
+ # default path where to mount gem,
59
+ # alternatively you can mount the RailsPerformance::Engine in your routes.rb
53
60
  config.mount_at = '/rails/performance'
54
61
 
55
62
  # protect your Performance Dashboard with HTTP BASIC password
@@ -65,6 +72,7 @@ end if defined?(RailsPerformance)
65
72
  ```
66
73
 
67
74
  ## Installation
75
+
68
76
  Add this line to your application's Gemfile:
69
77
 
70
78
  ```ruby
@@ -78,18 +86,47 @@ end
78
86
  ```
79
87
 
80
88
  And then execute:
89
+
81
90
  ```bash
82
91
  $ bundle
83
92
  ```
84
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
+
85
102
  You must also have installed Redis server, because this gem is storing data into it.
86
103
 
87
104
  After installation and configuration, start your Rails application, make a few requests, and open `https://localhost:3000/rails/performance` URL.
88
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
+
89
124
  ## How it works
90
125
 
91
126
  ![Schema](docs/rails_performance.png)
92
127
 
128
+ In addition it's wrapping gems internal methods and collecting performance information. See `./lib/rails_performance/gems/*` for more information.
129
+
93
130
  ## Limitations
94
131
 
95
132
  - it doesn't track params of POST/PUT requests
@@ -124,10 +161,8 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
124
161
 
125
162
  ## TODO
126
163
 
127
- - documentation in Readme
164
+ - documentation in Readme?
128
165
  - capture stacktrace of 500 errors and show in side panel
129
- - generator for initial config
130
- - CI for tests
131
166
  - time/zone config?
132
167
  - connected charts on dashboard, when zoom, when hover?
133
168
  - ability to zoom to see requests withing specific datetime range
@@ -136,7 +171,7 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
136
171
  - better stats tooltip, do not show if nothing to show
137
172
  - dark mode toggle? save to the cookies?
138
173
  - integration with elastic search? or other?
139
- - monitor active job (sidekiq)?
174
+ - monitor active job?
140
175
  - better logo?
141
176
  - number of requests last 24 hours, hour, etc.
142
177
  - collect deprecation.rails
@@ -144,17 +179,29 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
144
179
  - show "loading banner" until jquery is loaded?
145
180
  - better UI on smaller screens? Recent requests when URL's are long? Truncate with CSS?
146
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
147
186
 
148
187
  ## Contributing
149
188
 
150
189
  You are welcome to contribute. I've a big list of TODO.
151
190
 
191
+ If "schema" how records are stored i Redis is changed, and this is a breacking change, update: `RailsPerformance::SCHEMA` to a newer value.
192
+
152
193
  ## Big thanks to contributors
153
194
 
154
195
  - https://github.com/synth
155
196
  - https://github.com/alagos
156
197
  - https://github.com/klondaiker
198
+ - https://github.com/jules2689
199
+ - https://github.com/PedroAugustoRamalhoDuarte
200
+ - https://github.com/haffla
157
201
 
158
202
  ## License
159
203
 
160
204
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
205
+
206
+ [<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
207
+ />](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
  }
@@ -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 %>