Class: BackupNexus::Backup
- Inherits:
-
BaseRecord
- Object
- ActiveRecord::Base
- BaseRecord
- BackupNexus::Backup
- Defined in:
- app/models/backup_nexus/backup.rb
Class Method Summary collapse
-
.cleanup!(retention_days: 30) ⇒ Object
Cleanup old backup records.
-
.health_summary(alert_threshold_hours: 24) ⇒ Object
Get backup health summary.
-
.start!(config_name:, triggered_by: "system") ⇒ Object
Start tracking a backup run.
-
.success_rate(config_name:, days: 7) ⇒ Object
Get success rate for a model over the last N days.
Instance Method Summary collapse
-
#duration_human ⇒ Object
Duration formatted.
-
#fail!(error_message:) ⇒ Object
Mark backup as failed.
-
#file_size_human ⇒ Object
Format file size.
-
#succeed!(file_path: nil, file_size: nil) ⇒ Object
Mark backup as completed.
Class Method Details
.cleanup!(retention_days: 30) ⇒ Object
Cleanup old backup records
81 82 83 |
# File 'app/models/backup_nexus/backup.rb', line 81 def self.cleanup!(retention_days: 30) where("started_at < ?", retention_days.days.ago).delete_all end |
.health_summary(alert_threshold_hours: 24) ⇒ Object
Get backup health summary
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/backup_nexus/backup.rb', line 57 def self.health_summary(alert_threshold_hours: 24) configs = BackupNexus::BackupConfig.pluck(:name) results = configs.map do |config_name| latest = by_config(config_name).successful.latest_first.first age_hours = latest ? ((Time.current - latest.started_at) / 3600).round(1) : nil { config_name: config_name, last_backup: latest&.started_at, age_hours: age_hours, status: age_hours.nil? ? "unknown" : (age_hours < alert_threshold_hours ? "healthy" : "stale"), success_rate: success_rate(config_name: config_name), last_file_size: latest&.file_size } end { healthy: results.all? { |r| r[:status] == "healthy" }, models: results, alerts: results.select { |r| r[:status] == "stale" || r[:status] == "unknown" } } end |
.start!(config_name:, triggered_by: "system") ⇒ Object
Start tracking a backup run
19 20 21 22 23 24 25 26 |
# File 'app/models/backup_nexus/backup.rb', line 19 def self.start!(config_name:, triggered_by: "system") create!( config_name: config_name, status: "running", triggered_by: triggered_by, started_at: Time.current ) end |
.success_rate(config_name:, days: 7) ⇒ Object
Get success rate for a model over the last N days
50 51 52 53 54 |
# File 'app/models/backup_nexus/backup.rb', line 50 def self.success_rate(config_name:, days: 7) records = by_config(config_name).where("started_at >= ?", days.days.ago).where.not(status: "running") return 0 if records.empty? (records.successful.count.to_f / records.count * 100).round(1) end |
Instance Method Details
#duration_human ⇒ Object
Duration formatted
98 99 100 101 102 103 104 105 |
# File 'app/models/backup_nexus/backup.rb', line 98 def duration_human return "—" unless duration if duration < 60 "#{duration.round(1)}s" else "#{(duration / 60).floor}m #{(duration % 60).round}s" end end |
#fail!(error_message:) ⇒ Object
Mark backup as failed
40 41 42 43 44 45 46 47 |
# File 'app/models/backup_nexus/backup.rb', line 40 def fail!(error_message:) update!( status: "failed", error_message: , duration: (Time.current - started_at).round(2), completed_at: Time.current ) end |
#file_size_human ⇒ Object
Format file size
86 87 88 89 90 91 92 93 94 95 |
# File 'app/models/backup_nexus/backup.rb', line 86 def file_size_human return "—" unless file_size units = ["B", "KB", "MB", "GB"] size = file_size.to_f units.each do |unit| return "#{size.round(1)} #{unit}" if size < 1024 size /= 1024 end "#{size.round(1)} TB" end |
#succeed!(file_path: nil, file_size: nil) ⇒ Object
Mark backup as completed
29 30 31 32 33 34 35 36 37 |
# File 'app/models/backup_nexus/backup.rb', line 29 def succeed!(file_path: nil, file_size: nil) update!( status: "success", file_path: file_path, file_size: file_size, duration: (Time.current - started_at).round(2), completed_at: Time.current ) end |