activeinsights 0.2.3 → 0.3.1

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/active_insights/application_controller.rb +5 -1
  3. data/app/controllers/active_insights/jobs_controller.rb +13 -0
  4. data/app/controllers/active_insights/jobs_latencies_controller.rb +22 -0
  5. data/app/controllers/active_insights/jobs_p_values_controller.rb +33 -0
  6. data/app/controllers/active_insights/jpm_controller.rb +17 -0
  7. data/app/controllers/active_insights/requests_controller.rb +1 -1
  8. data/app/controllers/active_insights/requests_p_values_controller.rb +35 -0
  9. data/app/controllers/active_insights/rpm_controller.rb +1 -1
  10. data/app/helpers/active_insights/application_helper.rb +1 -1
  11. data/app/models/active_insights/job.rb +16 -0
  12. data/app/models/active_insights/record.rb +75 -0
  13. data/app/models/active_insights/request.rb +6 -70
  14. data/app/views/active_insights/jobs/index.html.erb +65 -0
  15. data/app/views/active_insights/jobs_latencies/index.html.erb +27 -0
  16. data/app/views/active_insights/{controller_p_values → jobs_p_values}/index.html.erb +9 -3
  17. data/app/views/active_insights/jpm/index.html.erb +26 -0
  18. data/app/views/active_insights/requests/index.html.erb +11 -7
  19. data/app/views/active_insights/{p_values → requests_p_values}/index.html.erb +9 -3
  20. data/app/views/active_insights/rpm/index.html.erb +1 -1
  21. data/app/views/layouts/active_insights/application.html.erb +7 -0
  22. data/config/routes.rb +25 -6
  23. data/db/migrate/{20240111225806_active_insights_request.rb → 20240111225806_create_active_insights_tables.rb} +19 -1
  24. data/lib/active_insights/engine.rb +11 -10
  25. data/lib/active_insights/seeders/jobs.rb +81 -0
  26. data/lib/active_insights/{seeder.rb → seeders/requests.rb} +3 -1
  27. data/lib/active_insights/version.rb +1 -1
  28. metadata +16 -10
  29. data/app/controllers/active_insights/controller_p_values_controller.rb +0 -24
  30. data/app/controllers/active_insights/p_values_controller.rb +0 -21
  31. data/vendor/javascript/chart.js.js +0 -10
  32. data/vendor/javascript/chartkick.js +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 005ff0ad5588288c42b05f56cb0134fc33bb90e1bcbb8599e8a97e784d1f0a5b
4
- data.tar.gz: f34eda95fcb2153ea8edf2aedc04a69a79373e4a0b765a86d5c7b83a6d4d291c
3
+ metadata.gz: e533b9e56ed98672b949403f1ad4ae1b533832abbea5376a6d225b1f73ae14f4
4
+ data.tar.gz: 20bfedf00b6b878643db9adce6d6608791dd1f0b1a0402219490d7d19cc5d104
5
5
  SHA512:
6
- metadata.gz: 0ea04ce1372e83d7cf3ab78291a44f3c232f74aabe2f099b5c0341aad166797051fd16409a6d838f82b32f99296b986993aace56260133df62e19069239f2599
7
- data.tar.gz: 517c8dd3c9cded15f006aec6f54ca6b45c33d2b19e7cf780c94d93a4587da8c248c8095730126b2206992904d505c266cf1168cd4eea9f80007b0c4fc68c3e50
6
+ metadata.gz: f1701580b1caff352a81e719f03e42b18365602c4904926a9d7da1076b44c417a6c416f7c78eb16b04bba158b157affe0d8a011a154cf97d6207bd023e1f2879
7
+ data.tar.gz: d4e7bbc7ab88d32c723991869909cf083edf40703f367adac38cc6f06fdd73d139de6bfad2758f086e6b688d07fb9394e07770844429ef650153dbc9289cc49a
@@ -25,7 +25,7 @@ module ActiveInsights
25
25
  end.beginning_of_day
26
26
  end
27
27
 
28
- def base_scope
28
+ def base_request_scope
29
29
  scope = ActiveInsights::Request.where(started_at: @date)
30
30
  if ActiveInsights.ignored_endpoints.present?
31
31
  scope = scope.where.
@@ -33,5 +33,9 @@ module ActiveInsights
33
33
  end
34
34
  scope
35
35
  end
36
+
37
+ def base_jobs_scope
38
+ ActiveInsights::Job.where(started_at: @date)
39
+ end
36
40
  end
37
41
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class JobsController < ApplicationController
5
+ def index
6
+ @jobs = base_jobs_scope.with_durations.select(:job, :queue).
7
+ group(:job, :queue).sort_by(&:agony).reverse
8
+
9
+ @latency =
10
+ base_jobs_scope.select("AVG(queue_time) as latency").to_a.first.latency
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class JobsLatenciesController < ApplicationController
5
+ def index
6
+ @latencies = minutes.map do |minute|
7
+ [minute.pretty_started_at, minute.latency.round(1)]
8
+ end
9
+ end
10
+
11
+ def redirection
12
+ redirect_to jobs_latency_path(params[:date])
13
+ end
14
+
15
+ private
16
+
17
+ def minutes
18
+ @minutes ||= base_jobs_scope.minute_by_minute.select_started_at.
19
+ select("AVG(queue_time) as latency")
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class JobsPValuesController < ApplicationController
5
+ def index
6
+ @p50 = minutes.map{ |minute| [minute.pretty_started_at, minute.p50] }
7
+ @p95 = minutes.map{ |minute| [minute.pretty_started_at, minute.p95] }
8
+ @p99 = minutes.map{ |minute| [minute.pretty_started_at, minute.p99] }
9
+ end
10
+
11
+ def redirection
12
+ if job.present?
13
+ redirect_to job_p_values_path(params[:date], job)
14
+ else
15
+ redirect_to jobs_p_values_path(params[:date])
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def minutes
22
+ @minutes ||= begin
23
+ scope = base_jobs_scope.minute_by_minute.with_durations
24
+ scope = scope.where(job:) if job.present?
25
+ scope.select_started_at
26
+ end
27
+ end
28
+
29
+ def job
30
+ params[:job].presence
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class JpmController < ApplicationController
5
+ def index
6
+ @minutes =
7
+ base_jobs_scope.minute_by_minute.select("COUNT(id) AS jpm").
8
+ select_started_at.map do |minute|
9
+ [minute.started_at.strftime("%-l:%M%P"), minute.jpm]
10
+ end
11
+ end
12
+
13
+ def redirection
14
+ redirect_to jpm_path(params[:date])
15
+ end
16
+ end
17
+ end
@@ -4,7 +4,7 @@ module ActiveInsights
4
4
  class RequestsController < ApplicationController
5
5
  def index
6
6
  @requests =
7
- base_scope.with_durations.select(:formatted_controller).
7
+ base_request_scope.with_durations.select(:formatted_controller).
8
8
  group(:formatted_controller).sort_by(&:agony).reverse
9
9
  end
10
10
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class RequestsPValuesController < ApplicationController
5
+ def index
6
+ @p50 = minutes.map{ |minute| [minute.pretty_started_at, minute.p50] }
7
+ @p95 = minutes.map{ |minute| [minute.pretty_started_at, minute.p95] }
8
+ @p99 = minutes.map{ |minute| [minute.pretty_started_at, minute.p99] }
9
+ end
10
+
11
+ def redirection
12
+ if formatted_controller.present?
13
+ redirect_to controller_p_values_path(params[:date],
14
+ formatted_controller)
15
+ else
16
+ redirect_to requests_p_values_path(params[:date])
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def minutes
23
+ @minutes ||= begin
24
+ scope = base_request_scope.minute_by_minute.with_durations
25
+ scope = scope.where(formatted_controller:) if
26
+ formatted_controller.present?
27
+ scope.select_started_at
28
+ end
29
+ end
30
+
31
+ def formatted_controller
32
+ params[:formatted_controller].presence
33
+ end
34
+ end
35
+ end
@@ -4,7 +4,7 @@ module ActiveInsights
4
4
  class RpmController < ApplicationController
5
5
  def index
6
6
  @minutes =
7
- base_scope.minute_by_minute.select("COUNT(id) AS rpm").
7
+ base_request_scope.minute_by_minute.select("COUNT(id) AS rpm").
8
8
  select_started_at.map do |minute|
9
9
  [minute.started_at.strftime("%-l:%M%P"), minute.rpm]
10
10
  end
@@ -32,7 +32,7 @@ module ActiveInsights
32
32
  end
33
33
 
34
34
  def per_minute(amount, duration)
35
- (amount / duration.in_minutes).round(0)
35
+ (amount / duration.in_minutes).round(1)
36
36
  end
37
37
 
38
38
  private
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInsights
4
+ class Job < ::ActiveInsights::Record
5
+ def self.setup(started, finished, unique_id, payload)
6
+ create!(started_at: started, finished_at: finished, uuid: unique_id,
7
+ db_runtime: payload[:db_runtime], job: payload[:job].class.to_s,
8
+ queue: payload[:job].queue_name,
9
+ scheduled_at: payload[:job].scheduled_at)
10
+ end
11
+
12
+ before_validation do
13
+ self.queue_time ||= (started_at - scheduled_at) * 1000.0
14
+ end
15
+ end
16
+ end
@@ -5,5 +5,80 @@ module ActiveInsights
5
5
  self.abstract_class = true
6
6
 
7
7
  connects_to(**ActiveInsights.connects_to) if ActiveInsights.connects_to
8
+
9
+ scope :with_durations, lambda {
10
+ case connection.adapter_name
11
+ when "SQLite"
12
+ select("JSON_GROUP_ARRAY(duration) AS durations")
13
+ when "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
14
+ select("JSON_ARRAYAGG(duration) AS durations")
15
+ when "PostgreSQL"
16
+ select("JSON_AGG(duration) AS durations")
17
+ end
18
+ }
19
+ scope :minute_by_minute, lambda {
20
+ case connection.adapter_name
21
+ when "SQLite"
22
+ group("strftime('%Y-%m-%d %H:%M:00 UTC', " \
23
+ "'#{table_name}'.'started_at')")
24
+ when "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
25
+ group("CONVERT_TZ(DATE_FORMAT(`#{table_name}`.`started_at`" \
26
+ ", '%Y-%m-%d %H:%i:00'), 'Etc/UTC', '+00:00')")
27
+ when "PostgreSQL"
28
+ group("DATE_TRUNC('minute', \"#{table_name}\"." \
29
+ "\"started_at\"::timestamptz AT TIME ZONE 'Etc/UTC') " \
30
+ "AT TIME ZONE 'Etc/UTC'")
31
+ end
32
+ }
33
+ scope :select_started_at, lambda {
34
+ case connection.adapter_name
35
+ when "SQLite", "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
36
+ select(:started_at)
37
+ when "PostgreSQL"
38
+ select("DATE_TRUNC('minute', \"#{table_name}\"." \
39
+ "\"started_at\"::timestamptz AT TIME ZONE 'Etc/UTC') " \
40
+ "AT TIME ZONE 'Etc/UTC' as started_at")
41
+ end
42
+ }
43
+
44
+ before_validation do
45
+ self.duration ||= (finished_at - started_at) * 1000.0
46
+ end
47
+
48
+ def agony
49
+ parsed_durations.sum
50
+ end
51
+
52
+ def parsed_durations
53
+ return unless respond_to?(:durations)
54
+
55
+ @parsed_durations ||=
56
+ if durations.is_a?(Array) then durations
57
+ else
58
+ JSON.parse(durations)
59
+ end.sort
60
+ end
61
+
62
+ def pretty_started_at
63
+ started_at.strftime("%-l:%M%P")
64
+ end
65
+
66
+ def p50
67
+ percentile_value(0.5)
68
+ end
69
+
70
+ def p95
71
+ percentile_value(0.95)
72
+ end
73
+
74
+ def p99
75
+ percentile_value(0.99)
76
+ end
77
+
78
+ private
79
+
80
+ def percentile_value(percentile)
81
+ parsed_durations[(percentile * parsed_durations.size).ceil - 1].round(1)
82
+ end
8
83
  end
9
84
  end
@@ -2,76 +2,12 @@
2
2
 
3
3
  module ActiveInsights
4
4
  class Request < ::ActiveInsights::Record
5
- scope :with_durations, lambda {
6
- case connection.adapter_name
7
- when "SQLite"
8
- select("JSON_GROUP_ARRAY(duration) AS durations")
9
- when "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
10
- select("JSON_ARRAYAGG(duration) AS durations")
11
- when "PostgreSQL"
12
- select("JSON_AGG(duration) AS durations")
13
- end
14
- }
15
- scope :minute_by_minute, lambda {
16
- case connection.adapter_name
17
- when "SQLite"
18
- group("strftime('%Y-%m-%d %H:%M:00 UTC', " \
19
- "'active_insights_requests'.'started_at')")
20
- when "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
21
- group("CONVERT_TZ(DATE_FORMAT(`active_insights_requests`.`started_at`" \
22
- ", '%Y-%m-%d %H:%i:00'), 'Etc/UTC', '+00:00')")
23
- when "PostgreSQL"
24
- group("DATE_TRUNC('minute', \"active_insights_requests\"." \
25
- "\"started_at\"::timestamptz AT TIME ZONE 'Etc/UTC') " \
26
- "AT TIME ZONE 'Etc/UTC'")
27
- end
28
- }
29
- scope :select_started_at, lambda {
30
- case connection.adapter_name
31
- when "SQLite", "Mysql2", "Mysql2Spatial", "Mysql2Rgeo", "Trilogy"
32
- select(:started_at)
33
- when "PostgreSQL"
34
- select("DATE_TRUNC('minute', \"active_insights_requests\"." \
35
- "\"started_at\"::timestamptz AT TIME ZONE 'Etc/UTC') " \
36
- "AT TIME ZONE 'Etc/UTC' as started_at")
37
- end
38
- }
39
-
40
- def agony
41
- parsed_durations.sum
42
- end
43
-
44
- def parsed_durations
45
- return unless respond_to?(:durations)
46
-
47
- @parsed_durations ||=
48
- if durations.is_a?(Array) then durations
49
- else
50
- JSON.parse(durations)
51
- end.sort
52
- end
53
-
54
- def pretty_started_at
55
- started_at.strftime("%-l:%M%P")
56
- end
57
-
58
- def p50
59
- percentile_value(0.5)
5
+ def self.setup(started, finished, unique_id, payload)
6
+ create!(started_at: started, finished_at: finished, uuid: unique_id,
7
+ http_method: payload[:method], **payload.slice(
8
+ :controller, :action, :format, :status, :view_runtime,
9
+ :db_runtime
10
+ ))
60
11
  end
61
-
62
- def p95
63
- percentile_value(0.95)
64
- end
65
-
66
- def p99
67
- percentile_value(0.99)
68
- end
69
-
70
- private
71
-
72
- def percentile_value(percentile)
73
- parsed_durations[(percentile * parsed_durations.size).ceil - 1].round(1)
74
- end
75
-
76
12
  end
77
13
  end
@@ -0,0 +1,65 @@
1
+ <header>
2
+ <h1>Metrics for <%= display_date(@date.first) %></h1>
3
+ <div class="flex flex-row items-center">
4
+ <%= link_to "View request metrics", active_insights.requests_path, class: "white mr-15px" %>
5
+
6
+ <%= form_with url: active_insights.jobs_path, method: :get do |f| %>
7
+ <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
8
+ <% f.submit "submit", class: "hidden" %>
9
+ <% end %>
10
+ </div>
11
+ </header>
12
+
13
+ <div class="pl-30px pt-30px flex flex-row justify-around font-size-30">
14
+ <% @jobs.flat_map(&:parsed_durations).tap do |durations| %>
15
+ <%= link_to jpm_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
16
+ <div><%= per_minute(durations.size, (@date.last - @date.first).seconds) %></div>
17
+ <b>JPM</b>
18
+ <% end %>
19
+
20
+ <%= link_to jobs_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
21
+ <div><%= p50(durations) %> ms</div>
22
+ <b>p50</b>
23
+ <% end %>
24
+
25
+ <%= link_to jobs_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
26
+ <div><%= p95(durations) %> ms</div>
27
+ <b>p95</b>
28
+ <% end %>
29
+
30
+ <%= link_to jobs_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
31
+ <div><%= p99(durations) %> ms</div>
32
+ <b>p99</b>
33
+ <% end %>
34
+
35
+ <%= link_to jobs_latency_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
36
+ <div><%= @latency.to_f.round(1) %> ms</div>
37
+ <b>Latency</b>
38
+ <% end %>
39
+ <% end %>
40
+ </div>
41
+
42
+ <table>
43
+ <thead>
44
+ <tr>
45
+ <th>Name</th>
46
+ <th>Queue</th>
47
+ <th>JPM</th>
48
+ <th>p50</th>
49
+ <th>p95</th>
50
+ <th>p99</th>
51
+ </tr>
52
+ </thead>
53
+ <tbody>
54
+ <% @jobs.each do |model| %>
55
+ <tr>
56
+ <td><%= link_to model.job, job_p_values_path(@date.first.to_date, model.job) %></td>
57
+ <td><%= model.queue %></td>
58
+ <td><%= per_minute(model.parsed_durations.size, (@date.last - @date.first).seconds) %></td>
59
+ <td><%= model.p50 %> ms</td>
60
+ <td><%= model.p95 %> ms</td>
61
+ <td><%= model.p99 %> ms</td>
62
+ </tr>
63
+ <% end %>
64
+ </tbody>
65
+ </table>
@@ -0,0 +1,27 @@
1
+ <header>
2
+ <h1>Job Latency for <%= display_date(@date.first) %> (in ms)</h1>
3
+
4
+ <%= form_with url: active_insights.jobs_latency_redirection_path, method: :get do |f| %>
5
+ <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
6
+ <% f.submit "submit", class: "hidden" %>
7
+ <% end %>
8
+ </header>
9
+
10
+ <div class="p-16px">
11
+ <%= column_chart @latencies, height: "80%", colors: ["#C00"], library: {
12
+ borderSkipped: true, barPercentage: 1, categoryPercentage: 1,
13
+ plugins: { zoom: { zoom: { wheel: { enabled: false }, drag: { enabled: true, backgroundColor: 'rgba(225,225,225,0.5)' }, mode: 'x' } } },
14
+ scales: {
15
+ x: { barPercentage: 1.0, autoSkip: false, display: false },
16
+ y: { grid: { display: false }, ticks: { color: "white" }, min: (@latencies.map(&:second).min.to_f * 0.98).ceil, max: (@latencies.map(&:second).max) }
17
+ } } %>
18
+ </div>
19
+
20
+ <script>
21
+ document.addEventListener('keydown',(event) => {
22
+ const chart = Chartkick.charts[Object.keys(Chartkick.charts)[0]].getChartObject()
23
+ if (event.key === 'Escape' || event.key === 'Esc') {
24
+ chart.resetZoom()
25
+ }
26
+ });
27
+ </script>
@@ -1,6 +1,12 @@
1
1
  <header>
2
- <h1><%= params[:formatted_controller] %> metrics for <%= display_date(@date.first) %> (in ms)</h1>
3
- <%= form_with url: active_insights.controller_p_values_redirection_path, method: :get do |f| %>
2
+ <% if params[:job].present? %>
3
+ <h1><%= params[:job] %> metrics for <%= display_date(@date.first) %> (in ms)</h1>
4
+ <% else %>
5
+ <h1>Job Metrics for <%= display_date(@date.first) %> (in ms)</h1>
6
+ <% end %>
7
+
8
+ <%= form_with url: active_insights.jobs_p_values_redirection_path, method: :get do |f| %>
9
+ <%= f.hidden_field :job, value: params[:job] %>
4
10
  <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
5
11
  <% f.submit "submit", class: "hidden" %>
6
12
  <% end %>
@@ -12,7 +18,7 @@
12
18
  elements: { point: { radius: 0 } },
13
19
  scales: {
14
20
  x: { autoSkip: false, display: false },
15
- y: { grid: { display: false }, ticks: { color: "white" }, min: (@p50.map(&:second).min * 0.98).ceil, max: (@p99.map(&:second).max) }
21
+ y: { grid: { display: false }, ticks: { color: "white" }, min: (@p50.map(&:second).min.to_f * 0.98).ceil, max: (@p99.map(&:second).max) }
16
22
  } } %>
17
23
  </div>
18
24
 
@@ -0,0 +1,26 @@
1
+ <header>
2
+ <h1>JPM Metrics for <%= display_date(@date.first) %></h1>
3
+ <%= form_with url: active_insights.jpm_redirection_path, method: :get do |f| %>
4
+ <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
5
+ <% f.submit "submit", class: "hidden" %>
6
+ <% end %>
7
+ </header>
8
+
9
+ <div class="p-16px">
10
+ <%= column_chart @minutes, height: "80%", colors: ["#C00"], library: {
11
+ borderSkipped: true, barPercentage: 1, categoryPercentage: 1,
12
+ plugins: { zoom: { zoom: { wheel: { enabled: false }, drag: { enabled: true, backgroundColor: 'rgba(225,225,225,0.5)' }, mode: 'x' } } },
13
+ scales: {
14
+ x: { barPercentage: 1.0, autoSkip: false, display: false },
15
+ y: { grid: { display: false }, ticks: { color: "white" }, min: (@minutes.map(&:second).min.to_f * 0.98).ceil, max: (@minutes.map(&:second).max) }
16
+ } } %>
17
+ </div>
18
+
19
+ <script>
20
+ document.addEventListener('keydown',(event) => {
21
+ const chart = Chartkick.charts[Object.keys(Chartkick.charts)[0]].getChartObject()
22
+ if (event.key === 'Escape' || event.key === 'Esc') {
23
+ chart.resetZoom()
24
+ }
25
+ });
26
+ </script>
@@ -1,9 +1,13 @@
1
1
  <header>
2
2
  <h1>Metrics for <%= display_date(@date.first) %></h1>
3
- <%= form_with url: active_insights.requests_path, method: :get do |f| %>
4
- <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
5
- <% f.submit "submit", class: "hidden" %>
6
- <% end %>
3
+ <div class="flex flex-row items-center">
4
+ <%= link_to "View job metrics", active_insights.jobs_path, class: "white mr-15px" %>
5
+
6
+ <%= form_with url: active_insights.requests_path, method: :get do |f| %>
7
+ <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
8
+ <% f.submit "submit", class: "hidden" %>
9
+ <% end %>
10
+ </div>
7
11
  </header>
8
12
 
9
13
  <div class="pl-30px pt-30px flex flex-row justify-around font-size-30">
@@ -13,17 +17,17 @@
13
17
  <b>RPM</b>
14
18
  <% end %>
15
19
 
16
- <%= link_to p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
20
+ <%= link_to requests_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
17
21
  <div><%= p50(durations) %> ms</div>
18
22
  <b>p50</b>
19
23
  <% end %>
20
24
 
21
- <%= link_to p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
25
+ <%= link_to requests_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
22
26
  <div><%= p95(durations) %> ms</div>
23
27
  <b>p95</b>
24
28
  <% end %>
25
29
 
26
- <%= link_to p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
30
+ <%= link_to requests_p_values_path(@date.first.to_date), class: "flex flex-col justify-center items-center no-underline" do %>
27
31
  <div><%= p99(durations) %> ms</div>
28
32
  <b>p99</b>
29
33
  <% end %>
@@ -1,6 +1,12 @@
1
1
  <header>
2
- <h1>Response Metrics for <%= display_date(@date.first) %> (in ms)</h1>
3
- <%= form_with url: active_insights.p_values_redirection_path, method: :get do |f| %>
2
+ <% if params[:formatted_controller].present? %>
3
+ <h1><%= params[:formatted_controller] %> metrics for <%= display_date(@date.first) %> (in ms)</h1>
4
+ <% else %>
5
+ <h1>Response Metrics for <%= display_date(@date.first) %> (in ms)</h1>
6
+ <% end %>
7
+
8
+ <%= form_with url: active_insights.requests_p_values_redirection_path, method: :get do |f| %>
9
+ <%= f.hidden_field :formatted_controller, value: params[:formatted_controller] %>
4
10
  <%= f.date_field :date, max: Date.current, onchange: "this.form.submit()", value: @date.first.to_date %>
5
11
  <% f.submit "submit", class: "hidden" %>
6
12
  <% end %>
@@ -12,7 +18,7 @@
12
18
  elements: { point: { radius: 0 } },
13
19
  scales: {
14
20
  x: { autoSkip: false, display: false },
15
- y: { grid: { display: false }, ticks: { color: "white" }, min: (@p50.map(&:second).min * 0.98).ceil, max: (@p99.map(&:second).max) }
21
+ y: { grid: { display: false }, ticks: { color: "white" }, min: (@p50.map(&:second).min.to_f * 0.98).ceil, max: (@p99.map(&:second).max) }
16
22
  } } %>
17
23
  </div>
18
24
 
@@ -12,7 +12,7 @@
12
12
  plugins: { zoom: { zoom: { wheel: { enabled: false }, drag: { enabled: true, backgroundColor: 'rgba(225,225,225,0.5)' }, mode: 'x' } } },
13
13
  scales: {
14
14
  x: { barPercentage: 1.0, autoSkip: false, display: false },
15
- y: { grid: { display: false }, ticks: { color: "white" }, min: (@minutes.map(&:second).min * 0.98).ceil, max: (@minutes.map(&:second).max) }
15
+ y: { grid: { display: false }, ticks: { color: "white" }, min: (@minutes.map(&:second).min.to_f * 0.98).ceil, max: (@minutes.map(&:second).max) }
16
16
  } } %>
17
17
  </div>
18
18
 
@@ -353,6 +353,13 @@
353
353
  padding: 16px;
354
354
  }
355
355
 
356
+ a.white {
357
+ color: #fff;
358
+ }
359
+ .mr-15px {
360
+ margin-right: 15px;
361
+ }
362
+
356
363
  <%= yield :style %>
357
364
  </style>
358
365
  </head>
data/config/routes.rb CHANGED
@@ -1,19 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ActiveInsights::Engine.routes.draw do
3
+ ActiveInsights::Engine.routes.draw do # rubocop:disable Metrics/BlockLength
4
4
  resources :requests, only: %i(index)
5
+ resources :jobs, only: %i(index)
6
+ get "/jobs/:date", to: "jobs#index"
5
7
  get "/requests/:date", to: "requests#index"
8
+
6
9
  get "/requests/rpm/redirection", to: "rpm#redirection", as: :rpm_redirection
7
10
  get "/requests/:date/rpm", to: "rpm#index", as: :rpm
8
11
 
9
- get "/requests/p_values/redirection", to: "p_values#redirection",
10
- as: :p_values_redirection
11
- get "/requests/:date/p_values", to: "p_values#index", as: :p_values
12
+ get "/requests/p_values/redirection", to: "requests_p_values#redirection",
13
+ as: :requests_p_values_redirection
14
+ get "/requests/:date/p_values", to: "requests_p_values#index", as: :requests_p_values
12
15
  get "/requests/:date/:formatted_controller/p_values",
13
- to: "controller_p_values#index", as: :controller_p_values
16
+ to: "requests_p_values#index", as: :controller_p_values
14
17
  get "/requests/:formatted_controller/p_values/redirection",
15
- to: "controller_p_values#redirection",
18
+ to: "requests_p_values#redirection",
16
19
  as: :controller_p_values_redirection
17
20
 
21
+ get "/jobs/jpm/redirection", to: "jpm#redirection", as: :jpm_redirection
22
+ get "/jobs/:date/jpm", to: "jpm#index", as: :jpm
23
+
24
+ get "/jobs/p_values/redirection", to: "jobs_p_values#redirection",
25
+ as: :jobs_p_values_redirection
26
+ get "/jobs/:date/p_values", to: "jobs_p_values#index", as: :jobs_p_values
27
+
28
+ get "/jobs/:date/:job/p_values", to: "jobs_p_values#index", as: :job_p_values
29
+ get "/jobs/:job/p_values/redirection",
30
+ to: "jobs_p_values#redirection",
31
+ as: :job_p_values_redirection
32
+
33
+ get "/jobs/:date/latencies", to: "jobs_latencies#index", as: :jobs_latency
34
+ get "/jobs/latencies/redirection", to: "jobs_latencies#redirection",
35
+ as: :jobs_latency_redirection
36
+
18
37
  root "requests#index"
19
38
  end