activeinsights 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ActiveInsightsRequest < ActiveRecord::Migration[7.1]
3
+ class CreateActiveInsightsTables < ActiveRecord::Migration[7.1]
4
4
  def change
5
5
  create_table :active_insights_requests, if_not_exists: true do |t|
6
6
  t.string :controller
@@ -28,5 +28,23 @@ class ActiveInsightsRequest < ActiveRecord::Migration[7.1]
28
28
 
29
29
  t.timestamps
30
30
  end
31
+
32
+ create_table :active_insights_jobs, if_not_exists: true do |t|
33
+ t.string :job
34
+ t.string :queue
35
+ t.float :db_runtime
36
+ t.datetime :scheduled_at
37
+ t.datetime :started_at
38
+ t.datetime :finished_at
39
+ t.string :uuid
40
+ t.float :duration
41
+ t.float :queue_time
42
+
43
+ t.index :started_at
44
+ t.index %i(started_at duration)
45
+ t.index %i(started_at duration queue_time)
46
+
47
+ t.timestamps
48
+ end
31
49
  end
32
50
  end
@@ -24,7 +24,15 @@ module ActiveInsights
24
24
  Engine.root.join("config/initializers/importmap.rb")
25
25
  end
26
26
 
27
- initializer "active_insights.subscriber" do |_app|
27
+ initializer "active_insights.job_subscriber" do
28
+ ActiveSupport::Notifications.
29
+ subscribe("perform.active_job") do |_name,
30
+ started, finished, unique_id, payload|
31
+ ActiveInsights::Job.setup(started, finished, unique_id, payload)
32
+ end
33
+ end
34
+
35
+ initializer "active_insights.request_subscriber" do
28
36
  ActiveSupport::Notifications.
29
37
  subscribe("process_action.action_controller") do |_name,
30
38
  started, finished, unique_id, payload|
@@ -33,15 +41,8 @@ module ActiveInsights
33
41
 
34
42
  Thread.new do
35
43
  ActiveRecord::Base.connection_pool.with_connection do
36
- ActiveInsights::Request.create!(
37
- started_at: started, finished_at: finished, uuid: unique_id,
38
- duration: (finished - started) * 1000.0,
39
- controller: payload[:controller],
40
- action: payload[:action], format: payload[:format],
41
- http_method: payload[:method], status: payload[:status],
42
- view_runtime: payload[:view_runtime],
43
- db_runtime: payload[:db_runtime]
44
- )
44
+ ActiveInsights::Request.
45
+ setup(started, finished, unique_id, payload)
45
46
  end
46
47
  end
47
48
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ require "rubystats"
5
+
6
+ module ActiveInsights
7
+ class JobSeeder
8
+ def initialize(date, rpm, p50, p95, p99)
9
+ @date = date
10
+ @rpm = rpm
11
+ @p50 = p50
12
+ @p95 = p95
13
+ @p99 = p99
14
+ end
15
+
16
+ def seed
17
+ ActiveInsights::Job.insert_all(seed_attributes)
18
+ end
19
+
20
+ def find_percentile(sorted_data, percentile)
21
+ sorted_data[(percentile * sorted_data.length).ceil - 1]
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :date, :rpm, :p50, :p95, :p99
27
+
28
+ def seed_attributes
29
+ 24.times.flat_map do |hour|
30
+ 60.times.flat_map do |min|
31
+ processing_times.map { |duration| attributes(hour, min, duration) }
32
+ end
33
+ end
34
+ end
35
+
36
+ def processing_times
37
+ Array.new(rpm) do
38
+ p50 + (beta_distribution.rng * (p95 - p50))
39
+ end.select { |time| time <= p99 }
40
+ end
41
+
42
+ def beta_distribution
43
+ @beta_distribution ||= Rubystats::BetaDistribution.new(2, 5)
44
+ end
45
+
46
+ def sample_job
47
+ %w(UserNotificationSenderJob DailyReportGeneratorJob DataCleanupWorkerJob
48
+ InvoiceProcessingJob EmailDigestSenderJob DatabaseBackupJob
49
+ OrderFulfillmentJob ProductCatalogUpdateJob MonthlyBillingJob
50
+ SubscriptionRenewalCheckerJob SocialMediaPostSchedulerJob
51
+ CustomerDataImporterJob SearchIndexRebuilderJob EventReminderSenderJob
52
+ FileExportJob).sample
53
+ end
54
+
55
+ def attributes(hour, min, duration)
56
+ started_at = date.dup.to_time.change(hour:, min:)
57
+ job = sample_job
58
+ queue = sample_queue(job)
59
+
60
+ default_attributes.merge(duration:, started_at:, job:, queue:,
61
+ scheduled_at: started_at - sample_latency,
62
+ finished_at: started_at + (duration / 1000.0))
63
+ end
64
+
65
+ def default_attributes
66
+ { created_at: Time.current, updated_at: Time.current,
67
+ uuid: SecureRandom.uuid }
68
+ end
69
+
70
+ def sample_latency
71
+ (1..500).to_a.sample.seconds
72
+ end
73
+
74
+ def sample_queue(job)
75
+ @sample_queues ||= {}
76
+ @sample_queues[job] ||=
77
+ %w(default mailers high_priority low_priority).sample
78
+ end
79
+ end
80
+ end
81
+ # :nocov:
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :nocov:
3
4
  require "rubystats"
4
5
 
5
6
  module ActiveInsights
6
- class Seeder
7
+ class RequestSeeder
7
8
  def initialize(date, rpm, p50, p95, p99)
8
9
  @date = date
9
10
  @rpm = rpm
@@ -64,3 +65,4 @@ module ActiveInsights
64
65
  end
65
66
  end
66
67
  end
68
+ # :nocov:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveInsights
4
- VERSION = "0.2.3"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeinsights
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Pezza
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-18 00:00:00.000000000 Z
11
+ date: 2024-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -62,29 +62,35 @@ files:
62
62
  - README.md
63
63
  - Rakefile
64
64
  - app/controllers/active_insights/application_controller.rb
65
- - app/controllers/active_insights/controller_p_values_controller.rb
66
- - app/controllers/active_insights/p_values_controller.rb
65
+ - app/controllers/active_insights/jobs_controller.rb
66
+ - app/controllers/active_insights/jobs_latencies_controller.rb
67
+ - app/controllers/active_insights/jobs_p_values_controller.rb
68
+ - app/controllers/active_insights/jpm_controller.rb
67
69
  - app/controllers/active_insights/requests_controller.rb
70
+ - app/controllers/active_insights/requests_p_values_controller.rb
68
71
  - app/controllers/active_insights/rpm_controller.rb
69
72
  - app/helpers/active_insights/application_helper.rb
73
+ - app/models/active_insights/job.rb
70
74
  - app/models/active_insights/record.rb
71
75
  - app/models/active_insights/request.rb
72
- - app/views/active_insights/controller_p_values/index.html.erb
73
- - app/views/active_insights/p_values/index.html.erb
76
+ - app/views/active_insights/jobs/index.html.erb
77
+ - app/views/active_insights/jobs_latencies/index.html.erb
78
+ - app/views/active_insights/jobs_p_values/index.html.erb
79
+ - app/views/active_insights/jpm/index.html.erb
74
80
  - app/views/active_insights/requests/index.html.erb
81
+ - app/views/active_insights/requests_p_values/index.html.erb
75
82
  - app/views/active_insights/rpm/index.html.erb
76
83
  - app/views/layouts/active_insights/application.html.erb
77
84
  - config/initializers/importmap.rb
78
85
  - config/routes.rb
79
- - db/migrate/20240111225806_active_insights_request.rb
86
+ - db/migrate/20240111225806_create_active_insights_tables.rb
80
87
  - lib/active_insights.rb
81
88
  - lib/active_insights/engine.rb
82
- - lib/active_insights/seeder.rb
89
+ - lib/active_insights/seeders/jobs.rb
90
+ - lib/active_insights/seeders/requests.rb
83
91
  - lib/active_insights/version.rb
84
92
  - lib/activeinsights.rb
85
93
  - lib/generators/active_insights/install/install_generator.rb
86
- - vendor/javascript/chart.js.js
87
- - vendor/javascript/chartkick.js
88
94
  homepage: https://github.com/npezza93/activeinsights
89
95
  licenses:
90
96
  - MIT
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveInsights
4
- class ControllerPValuesController < 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
- redirect_to controller_p_values_path(params[:date],
13
- params[:formatted_controller])
14
- end
15
-
16
- private
17
-
18
- def minutes
19
- @minutes ||=
20
- base_scope.where(formatted_controller: params[:formatted_controller]).
21
- minute_by_minute.with_durations.select_started_at
22
- end
23
- end
24
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveInsights
4
- class PValuesController < 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
- redirect_to p_values_path(params[:date])
13
- end
14
-
15
- private
16
-
17
- def minutes
18
- @minutes ||= base_scope.minute_by_minute.with_durations.select_started_at
19
- end
20
- end
21
- end