qa_server 7.3.0 → 7.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/app/jobs/qa_server/performance_per_byte_job.rb +85 -0
- data/app/models/concerns/qa_server/performance_history_data_keys.rb +8 -0
- data/app/services/qa_server/performance_per_byte_calculator_service.rb +88 -0
- data/app/services/qa_server/performance_per_byte_data_service.rb +41 -0
- data/lib/qa_server/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98cc1d63f4dab80fb1135ddbbef562943e596cae
|
4
|
+
data.tar.gz: 0e90cb6702c55c536e8d16d9e9d157127f695446
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 650b0109a2a047900a74272b1e1662a4ce90df5ce830bc47c3def63f115019c72c0ec2c757b25064de73de1694914781ea4a5c6fa0088f36da2a1bdaaceaed5d
|
7
|
+
data.tar.gz: 476c4f9489b0a0ea99df541ef1d7067c90b5b9555d24f26a122783947c6e9888a419a0a59161fbbdbd97a07210580e0ace2f6b98bfe63b95bec64316ffa58cb8
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Job to generate the performance day graph covering the last 24 hours.
|
3
|
+
module QaServer
|
4
|
+
class PerformancePerByteJob < ApplicationJob
|
5
|
+
include QaServer::PerformanceHistoryDataKeys
|
6
|
+
|
7
|
+
queue_as :default
|
8
|
+
|
9
|
+
class_attribute :authority_list_class, :data_service
|
10
|
+
self.authority_list_class = QaServer::AuthorityListerService
|
11
|
+
self.data_service = QaServer::PerformancePerByteDataService
|
12
|
+
# self.graphing_service = QaServer::PerformanceGraphingService
|
13
|
+
|
14
|
+
def perform(n: 10, action: :search, authority_complexity_ratings: {})
|
15
|
+
# checking active_job_id? prevents race conditions for long running jobs
|
16
|
+
generate_data_for_authorities(n, action, authority_complexity_ratings) if QaServer::JobIdCache.active_job_id?(job_key: job_key, job_id: job_id)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def generate_data_for_authorities(n, action, authority_complexity_ratings)
|
22
|
+
QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) - GENERATING performance by byte data")
|
23
|
+
auths = authority_list_class.authorities_list
|
24
|
+
data = if action.nil?
|
25
|
+
# generate_data_for_authority(ALL_AUTH, n) # generates data for all authorities
|
26
|
+
auths.each_with_object({}) { |authname, hash| hash[authname] = generate_data_for_authority(authname, n) }
|
27
|
+
else
|
28
|
+
auths.each_with_object({}) { |authname, hash| hash[authname] = { action => generate_data(authname, action, n) } }
|
29
|
+
end
|
30
|
+
QaServer.config.monitor_logger.debug("(#{self.class}-#{job_id}) COMPLETED performance by byte data generation")
|
31
|
+
QaServer::JobIdCache.reset_job_id(job_key: job_key)
|
32
|
+
convert_to_csv(data, authority_complexity_ratings)
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_data_for_authority(authority_name, n)
|
36
|
+
[SEARCH, FETCH, ALL_ACTIONS].each_with_object({}) do |action, hash|
|
37
|
+
hash[action] = generate_data(authority_name, action, n)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate_data(authority_name, action, n)
|
42
|
+
data_service.calculate(authority_name: authority_name, action: action, n: n)
|
43
|
+
# graphing_service.generate_day_graph(authority_name: authority_name, action: action, data: data)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param data [Hash] performance statistics based on size of data
|
47
|
+
# @param authority_complexity_ratings [Hash] complexity rating of the extended context included with results
|
48
|
+
# @example data
|
49
|
+
# { data_raw_bytes_from_source: [16271, 16271],
|
50
|
+
# retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
|
51
|
+
# retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
|
52
|
+
# graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
|
53
|
+
# graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
|
54
|
+
# normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
|
55
|
+
# normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
|
56
|
+
# }
|
57
|
+
def convert_to_csv(data, authority_complexity_ratings) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
58
|
+
performance_file = File.new('log/performance.csv', 'w')
|
59
|
+
performance_file.write("authority name, complexity_rating, action, size_bytes, ")
|
60
|
+
performance_file.write("retrieve_bytes_per_ms, graph_load_bytes_per_ms, normalize_bytes_per_ms, ")
|
61
|
+
performance_file.puts("retrieve_ms_per_byte, graph_load_ms_per_byte, normalize_ms_per_byte")
|
62
|
+
data.each do |auth_name, auth_data|
|
63
|
+
complexity_rating = authority_complexity_ratings.key?(auth_name) ? authority_complexity_ratings[auth_name] : "UNKNOWN"
|
64
|
+
auth_data.each do |action, action_data|
|
65
|
+
auth_action = "#{auth_name}, #{complexity_rating}, #{action}"
|
66
|
+
0.upto(action_data[:retrieve_bytes_per_ms].size - 1) do |idx|
|
67
|
+
performance_file.write(auth_action)
|
68
|
+
performance_file.write(", #{action_data[SRC_BYTES][idx]}")
|
69
|
+
performance_file.write(", #{action_data[BPMS_RETR][idx]}")
|
70
|
+
performance_file.write(", #{action_data[BPMS_GRPH][idx]}")
|
71
|
+
performance_file.write(", #{action_data[BPMS_NORM][idx]}")
|
72
|
+
performance_file.write(", #{action_data[MSPB_RETR][idx]}")
|
73
|
+
performance_file.write(", #{action_data[MSPB_GRPH][idx]}")
|
74
|
+
performance_file.puts(", #{action_data[MSPB_NORM][idx]}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
performance_file.close
|
79
|
+
end
|
80
|
+
|
81
|
+
def job_key
|
82
|
+
"QaServer::PerformanceByByteJob--job_id"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -38,5 +38,13 @@ module QaServer
|
|
38
38
|
HIGH_NORM = :high_normalization_ms
|
39
39
|
HIGH_ACTN = :high_action_request_ms
|
40
40
|
HIGH_FULL = :high_full_request_ms
|
41
|
+
|
42
|
+
SRC_BYTES = :data_raw_bytes_from_source
|
43
|
+
BPMS_RETR = :retrieve_bytes_per_ms
|
44
|
+
MSPB_RETR = :retrieve_ms_per_byte
|
45
|
+
BPMS_GRPH = :load_graph_bytes_per_ms
|
46
|
+
MSPB_GRPH = :load_graph_ms_per_byte
|
47
|
+
BPMS_NORM = :normalization_bytes_per_ms
|
48
|
+
MSPB_NORM = :normalization_ms_per_byte
|
41
49
|
end
|
42
50
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# This class calculates min, max, average stats for load, normalization, and full request times for a given set of performance records.
|
3
|
+
require 'matrix'
|
4
|
+
module QaServer
|
5
|
+
class PerformancePerByteCalculatorService
|
6
|
+
include QaServer::PerformanceHistoryDataKeys
|
7
|
+
|
8
|
+
TIME = 0
|
9
|
+
BYTES = 1
|
10
|
+
|
11
|
+
attr_reader :n, :stats, :records
|
12
|
+
|
13
|
+
# @param records [Array <Qa::PerformanceHistory>] set of records used to calculate the statistics
|
14
|
+
def initialize(records:, n:)
|
15
|
+
@records = records
|
16
|
+
@n = n
|
17
|
+
@stats = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Calculate performance statistics with percentiles. Min is at the 10th percentile. Max is at the 90th percentile.
|
21
|
+
# @return [Hash] hash of the statistics
|
22
|
+
# @example
|
23
|
+
# { data_raw_bytes_from_source: [16271, 16271],
|
24
|
+
# retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
|
25
|
+
# retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
|
26
|
+
# graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
|
27
|
+
# graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
|
28
|
+
# normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
|
29
|
+
# normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
|
30
|
+
# }
|
31
|
+
def calculate
|
32
|
+
extract_bytes
|
33
|
+
calculate_retrieve_stats
|
34
|
+
calculate_graph_load_stats
|
35
|
+
calculate_normalization_stats
|
36
|
+
stats
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def extract_bytes
|
42
|
+
stats[SRC_BYTES] = retrieve_data.count.zero? ? 0 : retrieve_data.map { |d| d[BYTES] }
|
43
|
+
end
|
44
|
+
|
45
|
+
def calculate_retrieve_stats
|
46
|
+
stats[BPMS_RETR] = calculate_bytes_per_ms(retrieve_data)
|
47
|
+
stats[MSPB_RETR] = calculate_ms_per_byte(retrieve_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def calculate_graph_load_stats
|
51
|
+
stats[BPMS_GRPH] = calculate_bytes_per_ms(graph_load_data)
|
52
|
+
stats[MSPB_GRPH] = calculate_ms_per_byte(graph_load_data)
|
53
|
+
end
|
54
|
+
|
55
|
+
def calculate_normalization_stats
|
56
|
+
stats[BPMS_NORM] = calculate_bytes_per_ms(norm_data)
|
57
|
+
stats[MSPB_NORM] = calculate_ms_per_byte(norm_data)
|
58
|
+
end
|
59
|
+
|
60
|
+
def calculate_bytes_per_ms(data)
|
61
|
+
return 0 if data.count.zero?
|
62
|
+
return data[0][BYTES] / d[0][TIME] if data.count == 1
|
63
|
+
data.map { |d| d[BYTES] / d[TIME] }
|
64
|
+
end
|
65
|
+
|
66
|
+
def calculate_ms_per_byte(data)
|
67
|
+
return 0 if data.count.zero?
|
68
|
+
return data[0][TIME] / d[0][BYTES] if data.count == 1
|
69
|
+
data.map { |d| d[TIME] / d[BYTES] }
|
70
|
+
end
|
71
|
+
|
72
|
+
def data(column)
|
73
|
+
records.where.not(column => nil).order(dt_stamp: :desc).limit(n).pluck(column, :size_bytes)
|
74
|
+
end
|
75
|
+
|
76
|
+
def retrieve_data
|
77
|
+
@retrieve_data ||= data(:retrieve_time_ms)
|
78
|
+
end
|
79
|
+
|
80
|
+
def graph_load_data
|
81
|
+
@graph_data ||= data(:graph_load_time_ms)
|
82
|
+
end
|
83
|
+
|
84
|
+
def norm_data
|
85
|
+
@norm_data ||= data(:normalization_time_ms)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# This class calculates performance stats based on size of data.
|
3
|
+
module QaServer
|
4
|
+
class PerformancePerByteDataService
|
5
|
+
class << self
|
6
|
+
include QaServer::PerformanceHistoryDataKeys
|
7
|
+
|
8
|
+
class_attribute :stats_calculator_class, :performance_data_class
|
9
|
+
self.stats_calculator_class = QaServer::PerformancePerByteCalculatorService
|
10
|
+
self.performance_data_class = QaServer::PerformanceHistory
|
11
|
+
|
12
|
+
# Performance data based on size of data.
|
13
|
+
# @param authority_name [String] name of an authority
|
14
|
+
# @param action [Symbol] :search, :fetch, or :all_actions
|
15
|
+
# @param n [Integer] calculate stats for last n records
|
16
|
+
# @returns [Hash] performance statistics based on size of data
|
17
|
+
# @example returns for n=2
|
18
|
+
# { data_raw_bytes_from_source: [16271, 16271],
|
19
|
+
# retrieve_bytes_per_ms: [67.24433786890475, 55.51210410757532],
|
20
|
+
# retrieve_ms_per_byte: [0.014871140555351083, 0.018014089288745542]
|
21
|
+
# graph_load_bytes_per_ms_ms: [86.74089418722461, 54.97464153778724],
|
22
|
+
# graph_load_ms_per_byte: [0.011528587632974647, 0.018190205011389522],
|
23
|
+
# normalization_bytes_per_ms: [64.70169466560836, 89.25337465693322],
|
24
|
+
# normalization_ms_per_byte: [0.01530700843338457, 0.015455545718983178]
|
25
|
+
# }
|
26
|
+
def calculate(authority_name:, action:, n: 10)
|
27
|
+
records = records_by(authority_name, action)
|
28
|
+
stats_calculator_class.new(records: records, n: n).calculate
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def records_by(authority_name, action)
|
34
|
+
where_clause = {}
|
35
|
+
where_clause[:authority] = authority_name unless authority_name.nil? || authority_name == ALL_AUTH
|
36
|
+
where_clause[:action] = action unless action.nil? || action == ALL_ACTIONS
|
37
|
+
performance_data_class.where(where_clause)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/qa_server/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qa_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- E. Lynette Rayle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -362,6 +362,7 @@ files:
|
|
362
362
|
- app/jobs/qa_server/monitor_tests_job.rb
|
363
363
|
- app/jobs/qa_server/performance_day_graph_job.rb
|
364
364
|
- app/jobs/qa_server/performance_month_graph_job.rb
|
365
|
+
- app/jobs/qa_server/performance_per_byte_job.rb
|
365
366
|
- app/jobs/qa_server/performance_year_graph_job.rb
|
366
367
|
- app/loggers/qa_server/scenario_logger.rb
|
367
368
|
- app/models/concerns/qa_server/performance_history_data_keys.rb
|
@@ -398,6 +399,8 @@ files:
|
|
398
399
|
- app/services/qa_server/performance_datatable_service.rb
|
399
400
|
- app/services/qa_server/performance_graph_data_service.rb
|
400
401
|
- app/services/qa_server/performance_graphing_service.rb
|
402
|
+
- app/services/qa_server/performance_per_byte_calculator_service.rb
|
403
|
+
- app/services/qa_server/performance_per_byte_data_service.rb
|
401
404
|
- app/services/qa_server/scenarios_loader_service.rb
|
402
405
|
- app/services/qa_server/time_period_service.rb
|
403
406
|
- app/services/qa_server/time_service.rb
|