activeinsights 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/active_insights/application_controller.rb +5 -1
- data/app/controllers/active_insights/jobs_controller.rb +13 -0
- data/app/controllers/active_insights/jobs_latencies_controller.rb +22 -0
- data/app/controllers/active_insights/jobs_p_values_controller.rb +33 -0
- data/app/controllers/active_insights/jpm_controller.rb +17 -0
- data/app/controllers/active_insights/requests_controller.rb +1 -1
- data/app/controllers/active_insights/requests_p_values_controller.rb +35 -0
- data/app/controllers/active_insights/rpm_controller.rb +1 -1
- data/app/helpers/active_insights/application_helper.rb +1 -1
- data/app/models/active_insights/job.rb +16 -0
- data/app/models/active_insights/record.rb +75 -0
- data/app/models/active_insights/request.rb +6 -70
- data/app/views/active_insights/jobs/index.html.erb +65 -0
- data/app/views/active_insights/jobs_latencies/index.html.erb +27 -0
- data/app/views/active_insights/{controller_p_values → jobs_p_values}/index.html.erb +9 -3
- data/app/views/active_insights/jpm/index.html.erb +26 -0
- data/app/views/active_insights/requests/index.html.erb +11 -7
- data/app/views/active_insights/{p_values → requests_p_values}/index.html.erb +9 -3
- data/app/views/active_insights/rpm/index.html.erb +1 -1
- data/app/views/layouts/active_insights/application.html.erb +7 -0
- data/config/routes.rb +25 -6
- data/db/migrate/{20240111225806_active_insights_request.rb → 20240111225806_create_active_insights_tables.rb} +19 -1
- data/lib/active_insights/engine.rb +11 -10
- data/lib/active_insights/seeders/jobs.rb +81 -0
- data/lib/active_insights/{seeder.rb → seeders/requests.rb} +3 -1
- data/lib/active_insights/version.rb +1 -1
- metadata +16 -10
- data/app/controllers/active_insights/controller_p_values_controller.rb +0 -24
- data/app/controllers/active_insights/p_values_controller.rb +0 -21
- data/vendor/javascript/chart.js.js +0 -10
- data/vendor/javascript/chartkick.js +0 -2
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class
|
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.
|
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.
|
37
|
-
|
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
|
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:
|
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.
|
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-
|
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/
|
66
|
-
- app/controllers/active_insights/
|
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/
|
73
|
-
- app/views/active_insights/
|
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/
|
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/
|
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
|