qa_server 2.2.1 → 2.2.2

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/app/assets/stylesheets/qa_server/_monitor-status.scss +8 -0
  4. data/app/controllers/qa_server/check_status_controller.rb +1 -1
  5. data/app/controllers/qa_server/monitor_status_controller.rb +71 -13
  6. data/app/models/concerns/qa_server/performance_history_data_keys.rb +29 -0
  7. data/app/models/qa_server/performance_history.rb +75 -179
  8. data/app/prepends/prepended_linked_data/find_term.rb +1 -1
  9. data/app/prepends/prepended_linked_data/search_query.rb +1 -1
  10. data/app/presenters/concerns/qa_server/monitor_status/gruff_graph.rb +0 -1
  11. data/app/presenters/concerns/qa_server/monitor_status/performance_datatable_behavior.rb +101 -0
  12. data/app/presenters/concerns/qa_server/monitor_status/performance_graph_behavior.rb +109 -0
  13. data/app/presenters/qa_server/monitor_status/performance_presenter.rb +4 -220
  14. data/app/presenters/qa_server/monitor_status_presenter.rb +8 -5
  15. data/app/services/qa_server/performance_calculator_service.rb +103 -0
  16. data/app/services/qa_server/performance_graph_data_service.rb +113 -0
  17. data/app/services/qa_server/performance_graphing_service.rb +113 -0
  18. data/app/views/qa_server/monitor_status/_performance.html.erb +90 -0
  19. data/app/views/qa_server/monitor_status/_test_history.html.erb +32 -0
  20. data/app/views/qa_server/monitor_status/_test_summary.html.erb +54 -0
  21. data/app/views/qa_server/monitor_status/index.html.erb +3 -182
  22. data/config/locales/qa_server.en.yml +11 -7
  23. data/lib/generators/qa_server/templates/config/initializers/qa_server.rb +26 -0
  24. data/lib/qa_server/configuration.rb +42 -0
  25. data/lib/qa_server/version.rb +1 -1
  26. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9a28076a2932c11c2dcfa1d833665d623ab3969
4
- data.tar.gz: 0e5eeb1c0c5535029f60c8a5f1a4bead059e4bbc
3
+ metadata.gz: fcedba0845e78467d54d898c86ad03498dbc1754
4
+ data.tar.gz: f00bc15be82518d374575eca094c418aa48cb78a
5
5
  SHA512:
6
- metadata.gz: f891059ddd3ef9453bf857dbd7e5cc0ce5cab4beead2897b02efac28803f82a06fb00fb94ce3de487e30bb00f085049e14c80052a8c80565ae4931401c962f7b
7
- data.tar.gz: e4c733a195568694b0bd9ed8fe7704aa62a3ab07c90c6ed2d3876869be33e439c68f28dc081c631182cb9b2dcba42a392b45420a5392a9079eb73c0e25c73040
6
+ metadata.gz: 4bd795410ea1f40b60595933d220a800bfeef12ca2bf7c9210cb3f8b6ff9ca3e77d085447ecea99b50d5f14f85ba359ec5a76533a51bce621dfc05120e465f43
7
+ data.tar.gz: 9f164a65faac0b9f73918b242a5d8eafbc1f769b492be648abf08a050e64b6df0e740962cdbd73777fc0f4f73d4f9f6cf896a7312d2135e0028335b593efaff8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ### 2.2.2 (2019-09-10)
2
+
3
+ * handle stat calculation and formatting when 0 records or missing stats
4
+ * switch performance graph to stacked_bar
5
+ * Use 10th and 90th percentiles for datatable
6
+ * display day graph for every authority for default time period
7
+ * cache performance graphs
8
+ * include authority data for performance graphs
9
+ * move some of the performance data construction code to services
10
+
1
11
  ### 2.2.1 (2019-09-04)
2
12
 
3
13
  * config to optionally display of the performance graph/datatable
@@ -12,6 +12,14 @@ p.status-update-dtstamp {
12
12
  font-style: italic;
13
13
  }
14
14
 
15
+ div.performance-data-section-hidden {
16
+ display: none;
17
+ }
18
+
19
+ div.performance-data-section-visible {
20
+ display: block;
21
+ }
22
+
15
23
  div.right-menu-section {
16
24
  padding-top: 50px;
17
25
  }
@@ -32,7 +32,7 @@ module QaServer
32
32
 
33
33
  def authority_name
34
34
  return @authority_name if @authority_name.present?
35
- @authority_name = (params.key? :authority) ? params[:authority].downcase : nil # rubocop:disable Style/TernaryParentheses
35
+ @authority_name = params.key?(:authority) ? params[:authority].downcase : nil
36
36
  end
37
37
  end
38
38
  end
@@ -6,7 +6,6 @@ module QaServer
6
6
  :scenario_run_registry_class,
7
7
  :scenario_history_class,
8
8
  :performance_history_class
9
-
10
9
  self.presenter_class = QaServer::MonitorStatusPresenter
11
10
  self.scenario_run_registry_class = QaServer::ScenarioRunRegistry
12
11
  self.scenario_history_class = QaServer::ScenarioRunHistory
@@ -14,15 +13,13 @@ module QaServer
14
13
 
15
14
  # Sets up presenter with data to display in the UI
16
15
  def index
17
- if refresh? || expired?
18
- validate(authorities_list)
19
- update_summary_and_data
20
- end
21
- # TODO: Include historical data and performance data too
16
+ refresh_tests
17
+ historical_data = refresh_history
18
+ performance_data = refresh_performance
22
19
  @presenter = presenter_class.new(current_summary: latest_summary,
23
20
  current_failure_data: latest_failures,
24
- historical_summary_data: historical_summary_data,
25
- performance_data: performance_history_class.performance_data)
21
+ historical_summary_data: historical_data,
22
+ performance_data: performance_data)
26
23
  render 'index', status: :internal_server_error if latest_summary.failing_authority_count.positive?
27
24
  end
28
25
 
@@ -46,20 +43,81 @@ module QaServer
46
43
  @latest_failures = nil # reset so next request recalculates
47
44
  end
48
45
 
49
- def historical_summary_data
50
- @historical_summary_data ||= scenario_history_class.historical_summary
51
- end
52
-
53
46
  def expired?
54
- latest_summary.blank? || latest_summary.run_dt_stamp < yesterday_midnight_et
47
+ @expired ||= latest_summary.blank? || latest_summary.run_dt_stamp < yesterday_midnight_et
55
48
  end
56
49
 
57
50
  def yesterday_midnight_et
58
51
  (DateTime.yesterday.midnight.to_time + 4.hours).to_datetime.in_time_zone("Eastern Time (US & Canada)")
59
52
  end
60
53
 
54
+ def historical_summary_data(refresh: false)
55
+ # TODO: Make this refresh the same way performance data refreshes.
56
+ # Requires historical graph to move out of presenter so it can be created here only with refresh.
57
+ if refresh
58
+ @historical_summary_data = scenario_history_class.historical_summary
59
+ # TODO: Need to recreate graph here. And need to only read the graph in presenter.
60
+ end
61
+ @historical_summary_data ||= scenario_history_class.historical_summary
62
+ end
63
+
64
+ def performance_data(refresh: false)
65
+ datatype = performance_datatype(refresh)
66
+ return if datatype == :none
67
+ @performance_data = nil if refresh
68
+ @performance_data ||= performance_history_class.performance_data(datatype: datatype)
69
+ end
70
+
71
+ def performance_datatype(refresh) # rubocop:disable Metrics/CyclomaticComplexity
72
+ return :all if display_performance_datatable? && display_performance_graph? && refresh
73
+ return :datatable if display_performance_datatable?
74
+ return :graph if display_performance_graph? && refresh
75
+ :none
76
+ end
77
+
78
+ def display_performance_datatable?
79
+ @display_performance_datatable ||= QaServer.config.display_performance_datatable?
80
+ end
81
+
82
+ def display_performance_graph?
83
+ @display_performance_graph ||= QaServer.config.display_performance_graph?
84
+ end
85
+
86
+ def refresh_tests
87
+ return unless refresh_tests?
88
+ validate(authorities_list)
89
+ update_summary_and_data
90
+ end
91
+
92
+ def refresh_history
93
+ historical_summary_data(refresh: refresh_history?)
94
+ end
95
+
96
+ def refresh_performance
97
+ performance_data(refresh: refresh_performance?)
98
+ end
99
+
61
100
  def refresh?
62
101
  params.key? :refresh
63
102
  end
103
+
104
+ def refresh_all?
105
+ params[:refresh].nil? || params[:refresh].casecmp?('all') # nil is for backward compatibility
106
+ end
107
+
108
+ def refresh_tests?
109
+ return false unless refresh? || expired?
110
+ refresh_all? || params[:refresh].casecmp?('tests') || expired?
111
+ end
112
+
113
+ def refresh_history?
114
+ return false unless refresh?
115
+ refresh_all? || params[:refresh].casecmp?('history')
116
+ end
117
+
118
+ def refresh_performance?
119
+ return false unless refresh?
120
+ refresh_all? || params[:refresh].casecmp?('performance')
121
+ end
64
122
  end
65
123
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ # This module sets up the hash keys for performance data and allows them to be used across all classes
3
+ # setting and reading from the performance data hash.
4
+ module QaServer
5
+ module PerformanceHistoryDataKeys
6
+ ALL_AUTH = :all_authorities
7
+ STATS = :stats
8
+ FOR_DATATABLE = :datatable_stats
9
+
10
+ FOR_DAY = :day
11
+ BY_HOUR = :hour
12
+
13
+ FOR_MONTH = :month
14
+ BY_DAY = :day
15
+
16
+ FOR_YEAR = :year
17
+ BY_MONTH = :month
18
+
19
+ LOW_LOAD = :low_load_ms
20
+ LOW_NORM = :low_normalization_ms
21
+ LOW_FULL = :low_full_request_ms
22
+ AVG_LOAD = :avg_load_ms
23
+ AVG_NORM = :avg_normalization_ms
24
+ AVG_FULL = :avg_full_request_ms
25
+ HIGH_LOAD = :max_load_ms
26
+ HIGH_NORM = :max_normalization_ms
27
+ HIGH_FULL = :max_full_request_ms
28
+ end
29
+ end
@@ -1,55 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
  # Provide access to the scenario_results_history database table which tracks specific scenario runs over time.
3
3
  module QaServer
4
- class PerformanceHistory < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
4
+ class PerformanceHistory < ActiveRecord::Base
5
5
  self.table_name = 'performance_history'
6
6
 
7
7
  enum action: [:fetch, :search]
8
8
 
9
- PERFORMANCE_ALL_KEY = :all_authorities
10
- PERFORMANCE_STATS_KEY = :stats
11
- PERFORMANCE_FOR_LIFETIME_KEY = :lifetime_stats
12
-
13
- PERFORMANCE_FOR_DAY_KEY = :day
14
- PERFORMANCE_BY_HOUR_KEY = :hour
15
-
16
- PERFORMANCE_FOR_MONTH_KEY = :month
17
- PERFORMANCE_BY_DAY_KEY = :day
18
-
19
- PERFORMANCE_FOR_YEAR_KEY = :year
20
- PERFORMANCE_BY_MONTH_KEY = :month
21
-
22
- SUM_LOAD_TIME_KEY = :load_sum_ms
23
- SUM_NORMALIZATION_TIME_KEY = :normalization_sum_ms
24
- SUM_FULL_REQUEST_TIME_KEY = :full_request_sum_ms
25
- MIN_LOAD_TIME_KEY = :load_min_ms
26
- MIN_NORMALIZATION_TIME_KEY = :normalization_min_ms
27
- MIN_FULL_REQUEST_TIME_KEY = :full_request_min_ms
28
- MAX_LOAD_TIME_KEY = :load_max_ms
29
- MAX_NORMALIZATION_TIME_KEY = :normalization_max_ms
30
- MAX_FULL_REQUEST_TIME_KEY = :full_request_max_ms
31
- AVG_LOAD_TIME_KEY = :load_avg_ms
32
- AVG_NORMALIZATION_TIME_KEY = :normalization_avg_ms
33
- AVG_FULL_REQUEST_TIME_KEY = :full_request_avg_ms
9
+ class_attribute :stats_calculator_class, :graph_data_service_class, :graphing_service_class, :authority_list_class
10
+ self.stats_calculator_class = QaServer::PerformanceCalculatorService
11
+ self.graph_data_service_class = QaServer::PerformanceGraphDataService
12
+ self.graphing_service_class = QaServer::PerformanceGraphingService
13
+ self.authority_list_class = QaServer::AuthorityListerService
34
14
 
35
15
  class << self
16
+ include QaServer::PerformanceHistoryDataKeys
17
+
36
18
  # Save a scenario result
37
19
  # @param run_id [Integer] the run on which to gather statistics
38
20
  # @param result [Hash] the scenario result to be saved
39
21
  def save_result(dt_stamp:, authority:, action:, size_bytes:, load_time_ms:, normalization_time_ms:) # rubocop:disable Metrics/ParameterLists
40
- QaServer::PerformanceHistory.create(dt_stamp: dt_stamp,
41
- authority: authority,
42
- action: action,
43
- size_bytes: size_bytes,
44
- load_time_ms: load_time_ms,
45
- normalization_time_ms: normalization_time_ms)
22
+ create(dt_stamp: dt_stamp,
23
+ authority: authority,
24
+ action: action,
25
+ size_bytes: size_bytes,
26
+ load_time_ms: load_time_ms,
27
+ normalization_time_ms: normalization_time_ms)
46
28
  end
47
29
 
48
- # Performance data for a day, a month, and a year.
30
+ # Performance data for a day, a month, a year, and all time for each authority.
31
+ # @param datatype [Symbol] what type of data should be calculated (e.g. :datatable, :graph, :all)
49
32
  # @returns [Hash] performance statistics for the past 24 hours
50
33
  # @example
51
34
  # { all_authorities:
52
- # { lifetime_stats:
35
+ # { datatable_stats:
53
36
  # { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }
54
37
  # }
55
38
  # { day:
@@ -76,179 +59,92 @@ module QaServer
76
59
  # 11: { month: '08-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }}
77
60
  # }
78
61
  # }
62
+ # { AGROVOC_LD4L_CACHE: ... # same data for each authority }
79
63
  # }
80
- def performance_data
81
- data = {}
82
- data[PERFORMANCE_ALL_KEY] = {
83
- PERFORMANCE_FOR_LIFETIME_KEY => lifetime,
84
- PERFORMANCE_FOR_DAY_KEY => average_last_24_hours,
85
- PERFORMANCE_FOR_MONTH_KEY => average_last_30_days,
86
- PERFORMANCE_FOR_YEAR_KEY => average_last_12_months
87
- }
64
+ def performance_data(datatype: :datatable)
65
+ return if datatype == :none
66
+ data = calculate_data(datatype)
67
+ graphing_service_class.create_performance_graphs(performance_data: data) if calculate_graphdata? datatype
88
68
  data
89
69
  end
90
70
 
91
71
  private
92
72
 
93
- # Get hourly average for the past 24 hours.
94
- # @returns [Hash] performance statistics across all records
95
- # @example
96
- # { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }
97
- def lifetime
98
- records = PerformanceHistory.all
99
- calculate_stats(records)
73
+ def calculate_datatable?(datatype)
74
+ datatype == :datatable || datatype == :all
100
75
  end
101
76
 
102
- # Get hourly average for the past 24 hours.
103
- # @returns [Hash] performance statistics for the past 24 hours
104
- # @example
105
- # { 0: { hour: '1400', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
106
- # 1: { hour: '1500', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
107
- # 2: { hour: '1600', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
108
- # ...,
109
- # 23: { hour: 'NOW', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }}
110
- # }
111
- def average_last_24_hours
112
- start_hour = Time.now.beginning_of_hour - 23.hours
113
- avgs = {}
114
- 0.upto(23).each do |idx|
115
- records = PerformanceHistory.where(dt_stamp: start_hour..start_hour.end_of_hour)
116
- stats = calculate_stats(records)
117
- data = {}
118
- data[PERFORMANCE_BY_HOUR_KEY] = performance_by_hour_label(idx, start_hour)
119
- data[PERFORMANCE_STATS_KEY] = stats
120
- avgs[idx] = data
121
- start_hour += 1.hour
122
- end
123
- avgs
77
+ def calculate_graphdata?(datatype)
78
+ datatype == :graph || datatype == :all
124
79
  end
125
80
 
126
- def performance_by_hour_label(idx, start_hour)
127
- if idx == 23
128
- I18n.t('qa_server.monitor_status.performance.now')
129
- elsif ((idx + 1) % 2).zero?
130
- (start_hour.hour * 100).to_s
131
- else
132
- ""
133
- end
81
+ def calculate_data(datatype)
82
+ data = {}
83
+ auths = authority_list_class.authorities_list
84
+ data[ALL_AUTH] = data_for_authority(datatype: datatype)
85
+ auths.each { |auth_name| data[auth_name] = data_for_authority(authority_name: auth_name, datatype: datatype) }
86
+ data
134
87
  end
135
88
 
136
- # Get daily average for the past 30 days.
137
- # @returns [Hash] performance statistics for the past 30 days
138
- # @example
139
- # { 0: { day: '07-15-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
140
- # 1: { day: '07-16-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
141
- # 2: { day: '07-17-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
142
- # ...,
143
- # 29: { day: 'TODAY', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }}
144
- # }
145
- def average_last_30_days
146
- start_day = Time.now.beginning_of_day - 29.days
147
- avgs = {}
148
- 0.upto(29).each do |idx|
149
- records = PerformanceHistory.where(dt_stamp: start_day..start_day.end_of_day)
150
- stats = calculate_stats(records)
151
- data = {}
152
- data[PERFORMANCE_BY_DAY_KEY] = performance_by_day_label(idx, start_day)
153
- data[PERFORMANCE_STATS_KEY] = stats
154
- avgs[idx] = data
155
- start_day += 1.day
89
+ def data_for_authority(authority_name: nil, datatype:)
90
+ data = {}
91
+ data[FOR_DATATABLE] = data_table_stats(authority_name) if calculate_datatable?(datatype)
92
+ if calculate_graphdata?(datatype)
93
+ data[FOR_DAY] = graph_data_service_class.average_last_24_hours(authority_name)
94
+ data[FOR_MONTH] = graph_data_service_class.average_last_30_days(authority_name)
95
+ data[FOR_YEAR] = graph_data_service_class.average_last_12_months(authority_name)
156
96
  end
157
- avgs
97
+ data
158
98
  end
159
99
 
160
- def performance_by_day_label(idx, start_day)
161
- if idx == 29
162
- I18n.t('qa_server.monitor_status.performance.today')
163
- elsif ((idx + 1) % 5).zero?
164
- start_day.strftime("%m-%d")
165
- else
166
- ""
167
- end
168
- end
169
-
170
- # Get daily average for the past 12 months.
171
- # @returns [Hash] performance statistics for the past 12 months
100
+ # Get statistics for all available data.
101
+ # @param [String] auth_name - limit statistics to records for the given authority (default: all authorities)
102
+ # @returns [Hash] performance statistics for the datatable during the expected time period
172
103
  # @example
173
- # { 0: { month: '09-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
174
- # 1: { month: '10-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
175
- # 2: { month: '11-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }},
176
- # ...,
177
- # 11: { month: '08-2019', stats: { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }}
178
- # }
179
- def average_last_12_months
180
- start_month = Time.now.beginning_of_month - 11.months
181
- avgs = {}
182
- 0.upto(11).each do |idx|
183
- records = PerformanceHistory.where(dt_stamp: start_month..start_month.end_of_month)
184
- stats = calculate_stats(records)
185
- data = {}
186
- data[PERFORMANCE_BY_MONTH_KEY] = start_month.strftime("%m-%Y")
187
- data[PERFORMANCE_STATS_KEY] = stats
188
- avgs[idx] = data
189
- start_month += 1.month
190
- end
191
- avgs
192
- end
193
-
194
- def calculate_stats(records)
195
- stats = init_stats
196
- return stats if records.count.zero?
197
- first = true
198
- records.each do |record|
199
- update_sum_stats(stats, record)
200
- update_min_stats(stats, record)
201
- update_max_stats(stats, record)
202
- first = false
203
- end
204
- calculate_avg_stats(stats, records)
205
- stats
104
+ # { load_avg_ms: 12.3, normalization_avg_ms: 4.2, full_request_avg_ms: 16.5, etc. }
105
+ def data_table_stats(auth_name)
106
+ records = records_for_last_24_hours(auth_name) ||
107
+ records_for_last_30_days(auth_name) ||
108
+ records_for_last_12_months(auth_name) ||
109
+ all_records(auth_name)
110
+ stats_calculator_class.new(records).calculate_stats(avg: true, low: true, high: true)
206
111
  end
207
112
 
208
- MIN_STARTING_TIME = 999_999_999
209
- def init_stats
210
- stats = {}
211
- stats[SUM_LOAD_TIME_KEY] = 0
212
- stats[SUM_NORMALIZATION_TIME_KEY] = 0
213
- stats[SUM_FULL_REQUEST_TIME_KEY] = 0
214
- stats[AVG_LOAD_TIME_KEY] = 0
215
- stats[AVG_NORMALIZATION_TIME_KEY] = 0
216
- stats[AVG_FULL_REQUEST_TIME_KEY] = 0
217
- stats[MIN_LOAD_TIME_KEY] = MIN_STARTING_TIME
218
- stats[MIN_NORMALIZATION_TIME_KEY] = MIN_STARTING_TIME
219
- stats[MIN_FULL_REQUEST_TIME_KEY] = MIN_STARTING_TIME
220
- stats[MAX_LOAD_TIME_KEY] = 0
221
- stats[MAX_NORMALIZATION_TIME_KEY] = 0
222
- stats[MAX_FULL_REQUEST_TIME_KEY] = 0
223
- stats
113
+ def expected_time_period
114
+ QaServer.config.performance_datatable_default_time_period
224
115
  end
225
116
 
226
- def update_sum_stats(stats, record)
227
- stats[SUM_LOAD_TIME_KEY] += record.load_time_ms
228
- stats[SUM_NORMALIZATION_TIME_KEY] += record.normalization_time_ms
229
- stats[SUM_FULL_REQUEST_TIME_KEY] += full_request_time_ms(record)
117
+ def records_for_last_24_hours(auth_name)
118
+ return unless expected_time_period == :day
119
+ end_hour = Time.now.getlocal
120
+ start_hour = end_hour - 23.hours
121
+ where_clause = { dt_stamp: start_hour..end_hour }
122
+ records_for_authority(auth_name, where_clause)
230
123
  end
231
124
 
232
- def update_min_stats(stats, record)
233
- stats[MIN_LOAD_TIME_KEY] = [stats[MIN_LOAD_TIME_KEY], record.load_time_ms].min
234
- stats[MIN_NORMALIZATION_TIME_KEY] = [stats[MIN_NORMALIZATION_TIME_KEY], record.normalization_time_ms].min
235
- stats[MIN_FULL_REQUEST_TIME_KEY] = [stats[MIN_FULL_REQUEST_TIME_KEY], full_request_time_ms(record)].min
125
+ def records_for_last_30_days(auth_name)
126
+ return unless expected_time_period == :month
127
+ end_day = Time.now.getlocal
128
+ start_day = end_day - 29.days
129
+ where_clause = { dt_stamp: start_day..end_day }
130
+ records_for_authority(auth_name, where_clause)
236
131
  end
237
132
 
238
- def update_max_stats(stats, record)
239
- stats[MAX_LOAD_TIME_KEY] = [stats[MAX_LOAD_TIME_KEY], record.load_time_ms].max
240
- stats[MAX_NORMALIZATION_TIME_KEY] = [stats[MAX_NORMALIZATION_TIME_KEY], record.normalization_time_ms].max
241
- stats[MAX_FULL_REQUEST_TIME_KEY] = [stats[MAX_FULL_REQUEST_TIME_KEY], full_request_time_ms(record)].max
133
+ def records_for_last_12_months(auth_name)
134
+ return unless expected_time_period == :year
135
+ end_month = Time.now.getlocal
136
+ start_month = end_month - 11.months
137
+ where_clause = { dt_stamp: start_month..end_month }
138
+ records_for_authority(auth_name, where_clause)
242
139
  end
243
140
 
244
- def calculate_avg_stats(stats, records)
245
- stats[AVG_LOAD_TIME_KEY] = stats[SUM_LOAD_TIME_KEY] / records.count
246
- stats[AVG_NORMALIZATION_TIME_KEY] = stats[SUM_NORMALIZATION_TIME_KEY] / records.count
247
- stats[AVG_FULL_REQUEST_TIME_KEY] = stats[SUM_FULL_REQUEST_TIME_KEY] / records.count
141
+ def all_records(auth_name)
142
+ auth_name.nil? ? PerformanceHistory.all : where(authority: auth_name)
248
143
  end
249
144
 
250
- def full_request_time_ms(record)
251
- record.load_time_ms + record.normalization_time_ms
145
+ def records_for_authority(auth_name, where_clause)
146
+ where_clause[:authority] = auth_name unless auth_name.nil?
147
+ where(where_clause)
252
148
  end
253
149
  end
254
150
  end
@@ -6,7 +6,7 @@ module PrependedLinkedData::FindTerm
6
6
  saved_performance_data = performance_data
7
7
  performance_data = true
8
8
  full_results = super
9
- QaServer::PerformanceHistory.save_result(dt_stamp: Time.now,
9
+ QaServer::PerformanceHistory.save_result(dt_stamp: Time.now.getlocal,
10
10
  authority: authority_name,
11
11
  action: 'fetch',
12
12
  size_bytes: full_results[:performance][:fetched_bytes],
@@ -6,7 +6,7 @@ module PrependedLinkedData::SearchQuery
6
6
  saved_performance_data = performance_data
7
7
  performance_data = true
8
8
  full_results = super
9
- QaServer::PerformanceHistory.save_result(dt_stamp: Time.now,
9
+ QaServer::PerformanceHistory.save_result(dt_stamp: Time.now.getlocal,
10
10
  authority: authority_name,
11
11
  action: 'search',
12
12
  size_bytes: full_results[:performance][:fetched_bytes],
@@ -18,4 +18,3 @@ module QaServer::MonitorStatus
18
18
  end
19
19
  end
20
20
  end
21
- # frozen_string_literal: true
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+ # This module provides access methods into the performance data hash.
3
+ module QaServer::MonitorStatus
4
+ module PerformanceDatatableBehavior
5
+ include QaServer::PerformanceHistoryDataKeys
6
+
7
+ def datatable_stats(authority_data)
8
+ authority_data[FOR_DATATABLE]
9
+ end
10
+
11
+ def low_load(stats)
12
+ format_stat stats[LOW_LOAD]
13
+ end
14
+
15
+ def low_normalization(stats)
16
+ format_stat stats[LOW_NORM]
17
+ end
18
+
19
+ def low_full_request(stats)
20
+ format_stat stats[LOW_FULL]
21
+ end
22
+
23
+ def high_load(stats)
24
+ format_stat stats[HIGH_LOAD]
25
+ end
26
+
27
+ def high_normalization(stats)
28
+ format_stat stats[HIGH_NORM]
29
+ end
30
+
31
+ def high_full_request(stats)
32
+ format_stat stats[HIGH_FULL]
33
+ end
34
+
35
+ def avg_load(stats)
36
+ format_stat stats[AVG_LOAD]
37
+ end
38
+
39
+ def avg_normalization(stats)
40
+ format_stat stats[AVG_NORM]
41
+ end
42
+
43
+ def avg_full_request(stats)
44
+ format_stat stats[AVG_FULL]
45
+ end
46
+
47
+ def low_full_request_style(stats)
48
+ performance_style_class(stats, LOW_FULL)
49
+ end
50
+
51
+ def high_full_request_style(stats)
52
+ performance_style_class(stats, HIGH_FULL)
53
+ end
54
+
55
+ def avg_full_request_style(stats)
56
+ performance_style_class(stats, AVG_FULL)
57
+ end
58
+
59
+ def performance_table_description
60
+ case expected_time_period
61
+ when :day
62
+ I18n.t('qa_server.monitor_status.performance.datatable_day_desc')
63
+ when :month
64
+ I18n.t('qa_server.monitor_status.performance.datatable_month_desc')
65
+ when :year
66
+ I18n.t('qa_server.monitor_status.performance.datatable_year_desc')
67
+ else
68
+ I18n.t('qa_server.monitor_status.performance.datatable_all_desc')
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def expected_time_period
75
+ QaServer.config.performance_datatable_default_time_period
76
+ end
77
+
78
+ def format_stat(stat)
79
+ return '' if stat.nil?
80
+ format("%0.1f", stat)
81
+ end
82
+
83
+ def performance_style_class(stats, stat_key)
84
+ return "status-bad" if max_threshold_exceeded(stats, stat_key)
85
+ return "status-unknown" if desired_threshold_not_met(stats, stat_key)
86
+ "status-good"
87
+ end
88
+
89
+ def max_threshold_exceeded(stats, stat_key)
90
+ return false if stats[stat_key].nil?
91
+ return true if stats[stat_key] > QaServer.config.performance_datatable_max_threshold
92
+ false
93
+ end
94
+
95
+ def desired_threshold_not_met(stats, stat_key)
96
+ return false if stats[stat_key].nil?
97
+ return true unless stats[stat_key] < QaServer.config.performance_datatable_warning_threshold
98
+ false
99
+ end
100
+ end
101
+ end