138 lines
4.0 KiB
JavaScript
138 lines
4.0 KiB
JavaScript
import config from '../../config.yaml'
|
|
|
|
import {
|
|
notifySlack,
|
|
getCheckLocation,
|
|
getKVMonitors,
|
|
setKVMonitors,
|
|
} from './helpers'
|
|
|
|
function getDate() {
|
|
return new Date().toISOString().split('T')[0]
|
|
}
|
|
|
|
export async function processCronTrigger(event) {
|
|
// Get Worker PoP and save it to monitorsStateMetadata
|
|
const checkLocation = await getCheckLocation()
|
|
const checkDay = getDate()
|
|
|
|
// Get monitors state from KV
|
|
let monitorsState = await getKVMonitors()
|
|
|
|
// Create empty state objects if not exists in KV storage yet
|
|
if (!monitorsState) {
|
|
monitorsState = { lastUpdate: {}, monitors: {} }
|
|
}
|
|
|
|
// Reset default all monitors state to true
|
|
monitorsState.lastUpdate.allOperational = true
|
|
|
|
for (const monitor of config.monitors) {
|
|
// Create default monitor state if does not exist yet
|
|
if (typeof monitorsState.monitors[monitor.id] === 'undefined') {
|
|
monitorsState.monitors[monitor.id] = {
|
|
firstCheck: checkDay,
|
|
lastCheck: {},
|
|
checks: {},
|
|
}
|
|
}
|
|
|
|
console.log(`Checking ${monitor.name} ...`)
|
|
|
|
// Fetch the monitors URL
|
|
const init = {
|
|
method: monitor.method || 'GET',
|
|
redirect: monitor.followRedirect ? 'follow' : 'manual',
|
|
headers: {
|
|
'User-Agent': config.settings.user_agent || 'cf-worker-status-page',
|
|
},
|
|
}
|
|
|
|
// Perform a check and measure time
|
|
const requestStartTime = Date.now()
|
|
const checkResponse = await fetch(monitor.url, init)
|
|
const requestTime = Math.round(Date.now() - requestStartTime)
|
|
|
|
// Determine whether operational and status changed
|
|
const monitorOperational =
|
|
checkResponse.status === (monitor.expectStatus || 200)
|
|
const monitorStatusChanged =
|
|
monitorsState.monitors[monitor.id].lastCheck.operational !==
|
|
monitorOperational
|
|
|
|
// Save monitor's last check response status
|
|
monitorsState.monitors[monitor.id].lastCheck = {
|
|
status: checkResponse.status,
|
|
statusText: checkResponse.statusText,
|
|
operational: monitorOperational,
|
|
}
|
|
|
|
// Send Slack message on monitor change
|
|
if (
|
|
monitorStatusChanged &&
|
|
typeof SECRET_SLACK_WEBHOOK_URL !== 'undefined' &&
|
|
SECRET_SLACK_WEBHOOK_URL !== 'default-gh-action-secret'
|
|
) {
|
|
event.waitUntil(notifySlack(monitor, monitorOperational))
|
|
}
|
|
|
|
// make sure checkDay exists in checks in cases when needed
|
|
if (
|
|
(config.settings.collectResponseTimes || !monitorOperational) &&
|
|
!monitorsState.monitors[monitor.id].checks.hasOwnProperty(checkDay)
|
|
) {
|
|
monitorsState.monitors[monitor.id].checks[checkDay] = {
|
|
fails: 0,
|
|
res: {},
|
|
}
|
|
}
|
|
|
|
if (config.settings.collectResponseTimes && monitorOperational) {
|
|
// make sure location exists in current checkDay
|
|
if (
|
|
!monitorsState.monitors[monitor.id].checks[checkDay].res.hasOwnProperty(
|
|
checkLocation,
|
|
)
|
|
) {
|
|
monitorsState.monitors[monitor.id].checks[checkDay].res[
|
|
checkLocation
|
|
] = {
|
|
n: 0,
|
|
ms: 0,
|
|
a: 0,
|
|
}
|
|
}
|
|
|
|
// increment number of checks and sum of ms
|
|
const no = ++monitorsState.monitors[monitor.id].checks[checkDay].res[
|
|
checkLocation
|
|
].n
|
|
const ms = (monitorsState.monitors[monitor.id].checks[checkDay].res[
|
|
checkLocation
|
|
].ms += requestTime)
|
|
|
|
// save new average ms
|
|
monitorsState.monitors[monitor.id].checks[checkDay].res[
|
|
checkLocation
|
|
].a = Math.round(ms / no)
|
|
} else if (!monitorOperational) {
|
|
// Save allOperational to false
|
|
monitorsState.lastUpdate.allOperational = false
|
|
|
|
// Increment failed checks, only on status change (maybe call it .incidents instead?)
|
|
if (monitorStatusChanged) {
|
|
monitorsState.monitors[monitor.id].checks[checkDay].fails++
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save last update information
|
|
monitorsState.lastUpdate.time = Date.now()
|
|
monitorsState.lastUpdate.loc = checkLocation
|
|
|
|
// Save monitorsState to KV storage
|
|
await setKVMonitors(monitorsState)
|
|
|
|
return new Response('OK')
|
|
}
|