Skip to content

Commit

Permalink
refactor: v2 per day
Browse files Browse the repository at this point in the history
  • Loading branch information
H01001000 committed Jul 1, 2024
1 parent d3aab30 commit 1217d48
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 106 deletions.
127 changes: 55 additions & 72 deletions poller/src/functions/cronTrigger.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
import config from '../../../config.json'
import type { ScheduledEvent } from '@cloudflare/workers-types'
import { MonitorDay, MonthSummery } from 'cf-status-page-types'

import {
getCheckLocation,
getKVMonitors,
setKVMonitors,
} from './helpers'

function getDate() {
return new Date().toISOString().split('T')[0]
function getDate(time: number) {
return new Date(time).toISOString().split('T')[0]
}

export async function processCronTrigger(_event: ScheduledEvent) {
// Get Worker PoP and save it to monitorsStateMetadata
// Get Worker PoP and save it to monitorDayMetadata
const checkLocation = await getCheckLocation()
const checkDay = getDate()
const now = Date.now()
const checkDay = getDate(now)

// Get monitors state from KV
let monitorsState = await getKVMonitors()
let monitorDay: MonitorDay = await getKVMonitors(checkDay)
// Create empty state objects if not exists in KV storage yet
if (!monitorsState) {
monitorsState = {
if (!monitorDay) {
const lastDay = getDate(now - 86400000)
const lastMonitorDay: MonitorDay = await getKVMonitors(lastDay)
if (lastMonitorDay) {
const month = lastDay.slice(0, 7)
let monthSummery: MonthSummery = await getKVMonitors(month)
if (!monthSummery)
monthSummery = {}
monthSummery[lastDay] = lastMonitorDay.checks.summery
await setKVMonitors(month, monthSummery)
}

monitorDay = {
lastCheck: now,
allOperational: true,
monitors: {}
operational: lastMonitorDay ? lastMonitorDay.operational : {},
checks: {
// incidents: {},
summery: {},
res: [],
}
}
}

monitorsState.allOperational = true
const res: {
t: number
l: string
ms: {
[index: string]: number | null
}
} = { t: now, l: checkLocation, ms: {} }

for (const monitor of config.monitors) {

Expand All @@ -44,97 +66,58 @@ export async function processCronTrigger(_event: ScheduledEvent) {
},
}

// Create default monitor state if does not exist yet
if (typeof monitorsState.monitors[monitor.id] === 'undefined') {
monitorsState.monitors[monitor.id] = {
operational: true,
incidents: [],
checks: {},
}
}

// Perform a check and measure time
const requestStartTime = performance.now()
const checkResponse = await fetch(monitor.url, init)
const requestTime = Math.round(performance.now() - requestStartTime)

// Determine whether operational and status changed
const monitorOperational = checkResponse.status === (monitor.expectStatus || 200)
const monitorStatusChanged = monitorsState.monitors[monitor.id].operational !== 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] = {
incidents: [],
summery: {},
res: [],
}
if (!monitorsState.monitors[monitor.id].operational) {
monitorsState.monitors[monitor.id].checks[checkDay].incidents.push(monitorsState.monitors[monitor.id].incidents.length - 1)
}
}
// const monitorStatusChanged = monitorDay.operational[monitor.id] ? monitorDay.operational[monitor.id] !== monitorOperational : false

// Save monitor's last check response status
monitorsState.monitors[monitor.id].operational = monitorOperational;
if (!monitorOperational) monitorsState.allOperational = false

monitorDay.operational[monitor.id] = monitorOperational;

if (config.settings.collectResponseTimes && monitorOperational) {
// make sure location exists in current checkDay
if (
!monitorsState.monitors[monitor.id].checks[checkDay].summery.hasOwnProperty(
checkLocation,
)
) {
monitorsState.monitors[monitor.id].checks[checkDay].summery[
checkLocation
] = {
if (!monitorDay.checks.summery[checkLocation])
monitorDay.checks.summery[checkLocation] = {}
if (!monitorDay.checks.summery[checkLocation][monitor.id])
monitorDay.checks.summery[checkLocation][monitor.id] = {
n: 0,
ms: 0,
a: 0,
}
}

// increment number of checks and sum of ms
const no = ++monitorsState.monitors[monitor.id].checks[checkDay].summery[
checkLocation
].n
const ms = (monitorsState.monitors[monitor.id].checks[checkDay].summery[
checkLocation
].ms += requestTime)
const no = ++monitorDay.checks.summery[checkLocation][monitor.id].n
const ms = monitorDay.checks.summery[checkLocation][monitor.id].ms += requestTime

// save new average ms
monitorsState.monitors[monitor.id].checks[checkDay].summery[
checkLocation
].a = Math.round(ms / no)
monitorDay.checks.summery[checkLocation][monitor.id].a = Math.round(ms / no)


monitorsState.monitors[monitor.id].checks[checkDay].res.push({
t: now,
loc: checkLocation,
ms: requestTime
})
res.ms[monitor.id] = monitorOperational ? requestTime : null

// back online
if (monitorStatusChanged) {
monitorsState.monitors[monitor.id].incidents.at(-1)!.end = now;
}
// if (monitorStatusChanged) {
// monitorDay.monitors[monitor.id].incidents.at(-1)!.end = now;
// }
}

// go dark
if (!monitorOperational && monitorStatusChanged) {
monitorsState.monitors[monitor.id].incidents.push({ start: now, status: checkResponse.status, statusText: checkResponse.statusText })
const incidentNumber = monitorsState.monitors[monitor.id].incidents.length - 1
monitorsState.monitors[monitor.id].checks[checkDay].incidents.push(incidentNumber)
}
// if (!monitorOperational && monitorStatusChanged) {
// monitorDay.monitors[monitor.id].incidents.push({ start: now, status: checkResponse.status, statusText: checkResponse.statusText })
// const incidentNumber = monitorDay.monitors[monitor.id].incidents.length - 1
// monitorDay.monitors[monitor.id].checks[checkDay].incidents.push(incidentNumber)
// }
}

monitorsState.lastCheck = now
monitorDay.checks.res.push(res)
monitorDay.lastCheck = now

// Save monitorsState to KV storage
await setKVMonitors(monitorsState)
// Save monitorDay to KV storage
await setKVMonitors(checkDay, monitorDay)

return new Response('OK')
}
12 changes: 4 additions & 8 deletions poller/src/functions/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import type { KvMonitors } from 'cf-status-page-types'

const kvDataKey = 'monitors_data_v1_1'

export async function getKVMonitors(): Promise<KvMonitors> {
export async function getKVMonitors(key: string): Promise<any> {
// trying both to see performance difference
//@ts-ignore
return (KV_STATUS_PAGE as KVNamespace).get(kvDataKey, 'json')
return (KV_STATUS_PAGE as KVNamespace).get(key, 'json')
//return JSON.parse(await KV_STATUS_PAGE.get(kvDataKey, 'text'))
}

export async function setKVMonitors(data: any) {
return setKV(kvDataKey, JSON.stringify(data))
export async function setKVMonitors(key: string, data: any) {
return setKV(key, JSON.stringify(data))
}

export async function setKV(key: string, value: string, metadata?: any | null, expirationTtl?: number) {
Expand Down
64 changes: 38 additions & 26 deletions types/src/KvMonitors.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
export interface Check {
incidents: number[],
export interface Checks {
// incidents: {
// [index: string]: {
// start: number
// status: number
// statusText: string
// end?: number
// }[]
// },
summery: {
[index: string]: {
n: number
ms: number
a: number
[index: string]: {
n: number
ms: number
a: number
}
}
},
res: {
t: number
loc: string
ms: number
l: string
ms: {
[index: string]: number | null
}
}[]
}

export interface KvMonitor {
operational: boolean
incidents: {
start: number
status: number
statusText: string
end?: number
}[],
checks: {
[index: string]: Check
}
}

export interface KvMonitors {
lastCheck: number
allOperational: boolean
monitors: {
[index: string]: KvMonitor
}
export interface MonitorDay {
lastCheck: number,
operational: {
[index: string]: boolean
},
checks: Checks
}

export interface MonthSummery {
// Date
[index: string]: {
// Location
[index: string]: {
// Monitor
[index: string]: {
n: number
ms: number
a: number
}
}
},
}

0 comments on commit 1217d48

Please sign in to comment.