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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd13388cd52b97f47cbc007512409654b26e4742
4
- data.tar.gz: 2e7fd2e75b65e662460c334cb9c87a39bb246e9e
3
+ metadata.gz: 98cc1d63f4dab80fb1135ddbbef562943e596cae
4
+ data.tar.gz: 0e90cb6702c55c536e8d16d9e9d157127f695446
5
5
  SHA512:
6
- metadata.gz: cc1aff80d3bf495a4dbedc6fdef33ec4e580f38d3e9953048ac5a991e550b807e5a772059a7ef934cada9243506ef48ef717ef973419a8b0bce8b1aae38de480
7
- data.tar.gz: aa8a277abc68f7db17bec6653990e5c3476e89d0860f670cf99f846cb82e26b76c187502c7bd059781a9212596184fd97654363b0b8be885cea29c1088fb94c2
6
+ metadata.gz: 650b0109a2a047900a74272b1e1662a4ce90df5ce830bc47c3def63f115019c72c0ec2c757b25064de73de1694914781ea4a5c6fa0088f36da2a1bdaaceaed5d
7
+ data.tar.gz: 476c4f9489b0a0ea99df541ef1d7067c90b5b9555d24f26a122783947c6e9888a419a0a59161fbbdbd97a07210580e0ace2f6b98bfe63b95bec64316ffa58cb8
@@ -1,3 +1,7 @@
1
+ ### 7.4.0 (2020-04-13)
2
+
3
+ * add size and complexity performance statistics (not auto-generated)
4
+
1
5
  ### 7.3.0 (2020-04-08)
2
6
 
3
7
  * move generation of graphs to background jobs
@@ -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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module QaServer
3
- VERSION = '7.3.0'
3
+ VERSION = '7.4.0'
4
4
  end
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.3.0
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-08 00:00:00.000000000 Z
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