Uptime computation

master
aeris 2021-01-31 22:00:50 +01:00
parent f1a61cd19b
commit 212bf0a36f
2 changed files with 61 additions and 1 deletions

View File

@ -34,6 +34,34 @@ class Service < ApplicationRecord
end
end
UPTIME_DURATIONS = [1.year, 1.month, 1.week, 1.day].freeze
def uptime
first_check = self.checks.order(created_at: :asc).limit(1).first
return nil unless first_check
now = Time.now.utc
uptime = UPTIME_DURATIONS.map { |d| [d, 0.second] }.to_h
ago = UPTIME_DURATIONS.map { |d| [d, d.ago(now).utc] }.to_h
start = ago.fetch UPTIME_DURATIONS.first
self.downs.where('"to" >= ?', start).each do |down|
UPTIME_DURATIONS.each do |duration|
start = ago[duration]
uptime[duration] += down.to.utc - [start, down.from.utc].max if start <= down.to
end
end
check_start = first_check.created_at.utc
uptime.map do |duration, downtime|
start = ago[duration]
max = [check_start, start].max
diff = (now - max).seconds
percentage = 1 - downtime / diff
[duration, percentage]
end.to_h
end
def last_check
self.checks.order(created_at: :desc).limit(1).first
end

View File

@ -13,7 +13,6 @@ describe Service do
.and_return(check)
now = Time.utc 2020, 01, 01, 00, 00, 00
from = nil
Timecop.freeze now do
allow(check).to receive(:ok?).and_return(true).at_least(:once)
expect { service.check! }.to not_change { ActionMailer::Base.deliveries.count } \
@ -54,4 +53,37 @@ describe Service do
end
end
end
describe :uptime do
let!(:service) { Service.create! name: :test, type: :ping, config: { host: 'example.org' } }
let!(:check) { service.checks.create! created_at: '2020-01-01', result: true }
it 'must exclude downtime prior to uptime period' do
service.downs.create! from: '2019-01-01', to: '2020-01-01'
Timecop.freeze 2021, 01, 01 do
expect(service.uptime[1.year]).to eq 1
end
end
it 'must only include the last downtime part of overlapping uptime period' do
service.downs.create! from: '2019-07-01', to: '2020-07-01'
Timecop.freeze 2021, 01, 01 do
expect(service.uptime[1.year]).to eq 1-(182.0/366)
end
end
it 'must include all the downtime later to uptime period' do
service.downs.create! from: '2020-03-01', to: '2020-07-01'
Timecop.freeze 2021, 01, 01 do
expect(service.uptime[1.year]).to eq 1-(122.0/366)
end
end
it 'must restrict uptime period if check created before' do
service.downs.create! from: '2020-03-01', to: '2020-07-01'
Timecop.freeze 2020, 06, 01 do
expect(service.uptime[1.year]).to eq 1-(122.0/152)
end
end
end
end