Class: PgInsights::HealthCheckResult
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- PgInsights::HealthCheckResult
- Defined in:
- app/models/pg_insights/health_check_result.rb
Constant Summary collapse
- VALID_CHECK_TYPES =
%w[ unused_indexes missing_indexes sequential_scans slow_queries table_bloat parameter_settings database_snapshot ].freeze
- VALID_STATUSES =
%w[pending running success error].freeze
Class Method Summary collapse
- .build_timeline_data(snapshots, parameter_changes) ⇒ Object
- .cleanup_old_snapshots ⇒ Object
- .compare_snapshots(snapshot1, snapshot2) ⇒ Object
- .detect_parameter_changes_since(days_ago = 7) ⇒ Object
- .find_snapshot_by_date(date) ⇒ Object
- .latest_for_type(check_type) ⇒ Object
- .latest_results ⇒ Object
- .latest_snapshot ⇒ Object
- .snapshots(limit = 90) ⇒ Object
- .snapshots_between(start_date, end_date) ⇒ Object
- .timeline_data(days = 30, parameter_changes = nil) ⇒ Object
Instance Method Summary collapse
Class Method Details
.build_timeline_data(snapshots, parameter_changes) ⇒ Object
133 134 135 136 137 138 139 140 141 142 |
# File 'app/models/pg_insights/health_check_result.rb', line 133 def self.build_timeline_data(snapshots, parameter_changes) { dates: snapshots.map { |s| s.executed_at.strftime("%Y-%m-%d %H:%M") }, cache_hit_rates: snapshots.map { |s| (s.result_data.dig("metrics", "cache_hit_rate") || 0).to_f }, avg_query_times: snapshots.map { |s| (s.result_data.dig("metrics", "avg_query_time") || 0).to_f }, bloated_tables: snapshots.map { |s| (s.result_data.dig("metrics", "bloated_tables") || 0).to_i }, total_connections: snapshots.map { |s| (s.result_data.dig("metrics", "total_connections") || 0).to_i }, parameter_changes: parameter_changes } end |
.cleanup_old_snapshots ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 |
# File 'app/models/pg_insights/health_check_result.rb', line 112 def self.cleanup_old_snapshots return unless PgInsights.snapshots_available? cutoff_date = PgInsights.snapshot_retention_days.days.ago deleted_count = by_type("database_snapshot") .where("executed_at < ?", cutoff_date) .delete_all Rails.logger.info "PgInsights: Cleaned up #{deleted_count} old snapshots" if deleted_count > 0 deleted_count end |
.compare_snapshots(snapshot1, snapshot2) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'app/models/pg_insights/health_check_result.rb', line 90 def self.compare_snapshots(snapshot1, snapshot2) return {} unless snapshot1&.result_data && snapshot2&.result_data params1 = snapshot1.result_data.dig("parameters") || {} params2 = snapshot2.result_data.dig("parameters") || {} changes = {} params2.each do |param_name, new_value| old_value = params1[param_name] if old_value != new_value && !both_nil_or_empty?(old_value, new_value) changes[param_name] = { from: old_value, to: new_value, change_type: determine_change_type(param_name, old_value, new_value), detected_at: snapshot2.executed_at } end end changes end |
.detect_parameter_changes_since(days_ago = 7) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/models/pg_insights/health_check_result.rb', line 69 def self.detect_parameter_changes_since(days_ago = 7) snapshots = by_type("database_snapshot") .successful .where("executed_at >= ?", days_ago.days.ago) .order(:executed_at) .to_a changes = [] snapshots.each_cons(2) do |older_snapshot, newer_snapshot| snapshot_changes = compare_snapshots(older_snapshot, newer_snapshot) if snapshot_changes.any? changes << { detected_at: newer_snapshot.executed_at, changes: snapshot_changes } end end changes end |
.find_snapshot_by_date(date) ⇒ Object
62 63 64 65 66 67 |
# File 'app/models/pg_insights/health_check_result.rb', line 62 def self.find_snapshot_by_date(date) by_type("database_snapshot") .successful .where("DATE(executed_at) = ?", date.to_date) .first end |
.latest_for_type(check_type) ⇒ Object
24 25 26 |
# File 'app/models/pg_insights/health_check_result.rb', line 24 def self.latest_for_type(check_type) by_type(check_type).successful.recent.first end |
.latest_results ⇒ Object
28 29 30 31 32 |
# File 'app/models/pg_insights/health_check_result.rb', line 28 def self.latest_results VALID_CHECK_TYPES.map do |check_type| [ check_type, latest_for_type(check_type) ] end.to_h end |
.latest_snapshot ⇒ Object
51 52 53 |
# File 'app/models/pg_insights/health_check_result.rb', line 51 def self.latest_snapshot by_type("database_snapshot").successful.recent.first end |
.snapshots(limit = 90) ⇒ Object
47 48 49 |
# File 'app/models/pg_insights/health_check_result.rb', line 47 def self.snapshots(limit = 90) by_type("database_snapshot").successful.recent.limit(limit) end |
.snapshots_between(start_date, end_date) ⇒ Object
55 56 57 58 59 60 |
# File 'app/models/pg_insights/health_check_result.rb', line 55 def self.snapshots_between(start_date, end_date) by_type("database_snapshot") .successful .where(executed_at: start_date.beginning_of_day..end_date.end_of_day) .order(:executed_at) end |
.timeline_data(days = 30, parameter_changes = nil) ⇒ Object
124 125 126 127 128 129 130 131 |
# File 'app/models/pg_insights/health_check_result.rb', line 124 def self.timeline_data(days = 30, parameter_changes = nil) snapshots = by_type("database_snapshot") .successful .where("executed_at >= ?", days.days.ago) .order(:executed_at) build_timeline_data(snapshots, parameter_changes || detect_parameter_changes_since(days)) end |
Instance Method Details
#error? ⇒ Boolean
38 39 40 |
# File 'app/models/pg_insights/health_check_result.rb', line 38 def error? status == "error" end |
#fresh?(threshold = nil) ⇒ Boolean
42 43 44 45 |
# File 'app/models/pg_insights/health_check_result.rb', line 42 def fresh?(threshold = nil) threshold ||= PgInsights.health_cache_expiry executed_at && executed_at > threshold.ago end |
#success? ⇒ Boolean
34 35 36 |
# File 'app/models/pg_insights/health_check_result.rb', line 34 def success? status == "success" end |