|
| 1 | +# frozen_string_literal: true |
| 2 | +# Provide access to the scenario_results_history database table which tracks specific scenario runs over time. |
| 3 | +module QaServer |
| 4 | + class PerformanceHistory < ActiveRecord::Base |
| 5 | + self.table_name = 'performance_history' |
| 6 | + |
| 7 | + enum action: [:fetch, :search] |
| 8 | + |
| 9 | + PERFORMANCE_FOR_DAY_KEY = :day |
| 10 | + PERFORMANCE_BY_HOUR_KEY = :hour |
| 11 | + |
| 12 | + PERFORMANCE_FOR_MONTH_KEY = :month |
| 13 | + PERFORMANCE_BY_DAY_KEY = :day |
| 14 | + |
| 15 | + PERFORMANCE_FOR_YEAR_KEY = :year |
| 16 | + PERFORMANCE_BY_MONTH_KEY = :month |
| 17 | + |
| 18 | + LOAD_TIME_KEY = :load_avg_ms |
| 19 | + NORMALIZATION_TIME_KEY = :normalization_avg_ms |
| 20 | + COMBINED_TIME_KEY = :combined_avg_ms |
| 21 | + |
| 22 | + class << self |
| 23 | + |
| 24 | + # Save a scenario result |
| 25 | + # @param run_id [Integer] the run on which to gather statistics |
| 26 | + # @param result [Hash] the scenario result to be saved |
| 27 | + def save_result(dt_stamp:, authority:, action:, size_bytes:, load_time_ms:, normalization_time_ms: ) |
| 28 | + QaServer::PerformanceHistory.create(dt_stamp: dt_stamp, |
| 29 | + authority: authority, |
| 30 | + action: action, |
| 31 | + size_bytes: size_bytes, |
| 32 | + load_time_ms: load_time_ms, |
| 33 | + normalization_time_ms: normalization_time_ms) |
| 34 | + end |
| 35 | + |
| 36 | + # Performance data for a day, a month, and a year. |
| 37 | + # @returns [Hash] performance statistics for the past 24 hours |
| 38 | + # @example |
| 39 | + # { 0: { hour: 1400, load_avg_ms: 12.3, normalization_avg_ms: 4.2 }, |
| 40 | + # 1: { hour: 1500, load_avg_ms: 12.3, normalization_avg_ms: 4.2 }, |
| 41 | + # 2: { hour: 1600, load_avg_ms: 12.3, normalization_avg_ms: 4.2 }, |
| 42 | + # ..., |
| 43 | + # 23: { hour: 1300, load_avg_ms: 12.3, normalization_avg_ms: 4.2 } |
| 44 | + # } |
| 45 | + def performance_data |
| 46 | + data = {} |
| 47 | + data[PERFORMANCE_FOR_DAY_KEY] = average_last_24_hours |
| 48 | + data[PERFORMANCE_FOR_MONTH_KEY] = average_last_30_days |
| 49 | + data[PERFORMANCE_FOR_YEAR_KEY] = average_last_12_months |
| 50 | + data |
| 51 | + end |
| 52 | + |
| 53 | + private |
| 54 | + |
| 55 | + # Get hourly average for the past 24 hours. |
| 56 | + # @returns [Hash] performance statistics for the past 24 hours |
| 57 | + # @example |
| 58 | + # { 0: { hour: 1400, load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 59 | + # 1: { hour: 1500, load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 60 | + # 2: { hour: 1600, load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 61 | + # ..., |
| 62 | + # 23: { hour: 1300, load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 } |
| 63 | + # } |
| 64 | + def average_last_24_hours |
| 65 | + start_hour = Time.now.beginning_of_hour - 23.hour |
| 66 | + avgs = {} |
| 67 | + 0.upto(23).each do |idx| |
| 68 | + records = PerformanceHistory.where(dt_stamp: start_hour..start_hour.end_of_hour) |
| 69 | + averages = calculate_averages(records) |
| 70 | + data = {} |
| 71 | + data[PERFORMANCE_BY_HOUR_KEY] = idx == 23 ? I18n.t('qa_server.monitor_status.performance.now') : ((idx + 1) % 2 == 0 ? (start_hour.hour * 100).to_s : "") |
| 72 | + data[LOAD_TIME_KEY] = averages[:avg_load_time_ms] |
| 73 | + data[NORMALIZATION_TIME_KEY] = averages[:avg_normalization_time_ms] |
| 74 | + data[COMBINED_TIME_KEY] = averages[:avg_combined_time_ms] |
| 75 | + avgs[idx] = data |
| 76 | + start_hour = start_hour + 1.hour |
| 77 | + end |
| 78 | + avgs |
| 79 | + end |
| 80 | + |
| 81 | + # Get daily average for the past 30 days. |
| 82 | + # @returns [Hash] performance statistics for the past 30 days |
| 83 | + # @example |
| 84 | + # { 0: { day: '07-15-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 85 | + # 1: { day: '07-16-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 86 | + # 2: { day: '07-17-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 87 | + # ..., |
| 88 | + # 29: { day: '08-13-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 } |
| 89 | + # } |
| 90 | + def average_last_30_days |
| 91 | + start_day = Time.now.beginning_of_day - 29.day |
| 92 | + avgs = {} |
| 93 | + 0.upto(29).each do |idx| |
| 94 | + records = PerformanceHistory.where(dt_stamp: start_day..start_day.end_of_day) |
| 95 | + averages = calculate_averages(records) |
| 96 | + data = {} |
| 97 | + data[PERFORMANCE_BY_DAY_KEY] = idx == 29 ? I18n.t('qa_server.monitor_status.performance.today') : ((idx + 1) % 5 == 0 ? (start_day).strftime("%m-%d") : "") |
| 98 | + data[LOAD_TIME_KEY] = averages[:avg_load_time_ms] |
| 99 | + data[NORMALIZATION_TIME_KEY] = averages[:avg_normalization_time_ms] |
| 100 | + data[COMBINED_TIME_KEY] = averages[:avg_combined_time_ms] |
| 101 | + avgs[idx] = data |
| 102 | + start_day = start_day + 1.day |
| 103 | + end |
| 104 | + avgs |
| 105 | + end |
| 106 | + |
| 107 | + # Get daily average for the past 12 months. |
| 108 | + # @returns [Hash] performance statistics for the past 12 months |
| 109 | + # @example |
| 110 | + # { 0: { month: '09-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 111 | + # 1: { month: '10-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 112 | + # 2: { month: '11-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 }, |
| 113 | + # ..., |
| 114 | + # 11: { month: '08-2019', load_avg_ms: 12.3, normalization_avg_ms: 4.2, combined_avg_ms: 16.5 } |
| 115 | + # } |
| 116 | + def average_last_12_months |
| 117 | + start_month = Time.now.beginning_of_month - 11.month |
| 118 | + avgs = {} |
| 119 | + 0.upto(11).each do |idx| |
| 120 | + records = PerformanceHistory.where(dt_stamp: start_month..start_month.end_of_month) |
| 121 | + averages = calculate_averages(records) |
| 122 | + data = {} |
| 123 | + data[PERFORMANCE_BY_MONTH_KEY] = (start_month).strftime("%m-%Y") |
| 124 | + data[LOAD_TIME_KEY] = averages[:avg_load_time_ms] |
| 125 | + data[NORMALIZATION_TIME_KEY] = averages[:avg_normalization_time_ms] |
| 126 | + data[COMBINED_TIME_KEY] = averages[:avg_combined_time_ms] |
| 127 | + avgs[idx] = data |
| 128 | + start_month = start_month + 1.month |
| 129 | + end |
| 130 | + avgs |
| 131 | + end |
| 132 | + |
| 133 | + def calculate_averages(records) |
| 134 | + return { avg_load_time_ms: 0, avg_normalization_time_ms: 0, avg_combined_time_ms: 0 } if records.count.zero? |
| 135 | + sum_load_times = 0 |
| 136 | + sum_normalization_times = 0 |
| 137 | + sum_combined_times = 0 |
| 138 | + records.each do |record| |
| 139 | + sum_load_times += record.load_time_ms |
| 140 | + sum_normalization_times += record.normalization_time_ms |
| 141 | + sum_combined_times += (record.load_time_ms + record.normalization_time_ms) |
| 142 | + end |
| 143 | + { |
| 144 | + avg_load_time_ms: sum_load_times / records.count, |
| 145 | + avg_normalization_time_ms: sum_normalization_times / records.count, |
| 146 | + avg_combined_time_ms: sum_combined_times / records.count |
| 147 | + } |
| 148 | + end |
| 149 | + end |
| 150 | + end |
| 151 | +end |
0 commit comments