1
0
mirror of https://github.com/tormachris/cf-workers-status-page.git synced 2024-11-23 14:45:41 +01:00

feat: collect avg response time by default

This commit is contained in:
Adam Janiš 2021-01-19 00:18:32 +01:00
parent 1439b67c30
commit 6d08f47d1d
6 changed files with 66 additions and 30 deletions

View File

@ -5,6 +5,8 @@ on:
branches: branches:
- main - main
repository_dispatch: repository_dispatch:
schedule:
- cron: '0 0 1 * *'
jobs: jobs:
deploy: deploy:

View File

@ -3,7 +3,7 @@ settings:
url: 'https://status-page.eidam.dev' # used for Slack messages url: 'https://status-page.eidam.dev' # used for Slack messages
logo: logo-192x192.png # image in ./public/ folder logo: logo-192x192.png # image in ./public/ folder
daysInHistogram: 90 # number of days you want to display in histogram daysInHistogram: 90 # number of days you want to display in histogram
collectResponseTimes: false # experimental feature, enable only for <5 monitors or on paid plans collectResponseTimes: true # collects avg response times from CRON locations
allmonitorsOperational: 'All Systems Operational' allmonitorsOperational: 'All Systems Operational'
notAllmonitorsOperational: 'Not All Systems Operational' notAllmonitorsOperational: 'Not All Systems Operational'

View File

@ -6,7 +6,7 @@ const accountId = process.env.CF_ACCOUNT_ID
const namespaceId = process.env.KV_NAMESPACE_ID const namespaceId = process.env.KV_NAMESPACE_ID
const apiToken = process.env.CF_API_TOKEN const apiToken = process.env.CF_API_TOKEN
const kvPrefix = 's_' const kvMonitorsKey = 'monitors_data_v1_1'
if (!accountId || !namespaceId || !apiToken) { if (!accountId || !namespaceId || !apiToken) {
console.error( console.error(
@ -15,7 +15,7 @@ if (!accountId || !namespaceId || !apiToken) {
process.exit(0) process.exit(0)
} }
async function getKvMonitors(kvPrefix) { async function getKvMonitors(kvMonitorsKey) {
const init = { const init = {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -24,27 +24,29 @@ async function getKvMonitors(kvPrefix) {
} }
const res = await fetch( const res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/keys?limit=100&prefix=${kvPrefix}`, `https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${kvMonitorsKey}`,
init, init,
) )
const json = await res.json() const json = await res.json()
return json.result return json
} }
async function deleteKvBulk(keys) { async function saveKVMonitors(kvMonitorsKey, data) {
const init = { const init = {
method: 'PUT',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`, Authorization: `Bearer ${apiToken}`,
}, },
method: 'DELETE', body: JSON.stringify(data),
body: JSON.stringify(keys),
} }
return await fetch( const res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/bulk`, `https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${kvMonitorsKey}`,
init, init,
) )
return res
} }
function loadConfig() { function loadConfig() {
@ -53,26 +55,37 @@ function loadConfig() {
return JSON.parse(config) return JSON.parse(config)
} }
getKvMonitors(kvPrefix) getKvMonitors(kvMonitorsKey)
.then(async (kvMonitors) => { .then(async (kvMonitors) => {
let stateMonitors = kvMonitors
const config = loadConfig() const config = loadConfig()
const monitors = config.monitors.map((key) => { const configMonitors = config.monitors.map((key) => {
return key.id return key.id
}) })
const kvState = kvMonitors.map((key) => {
return key.name
})
const keysForRemoval = kvState.filter(
(x) => !monitors.includes(x.replace(kvPrefix, '')),
)
if (keysForRemoval.length > 0) { Object.keys(stateMonitors.monitors).map((monitor) => {
console.log( // remove monitor data from state if missing in config
`Removing following keys from KV storage as they are no longer in the config: ${keysForRemoval.join( if (!configMonitors.includes(monitor)) {
', ', delete stateMonitors.monitors[monitor]
)}`, }
)
await deleteKvBulk(keysForRemoval) // delete dates older than config.settings.daysInHistogram
let date = new Date()
date.setDate(date.getDate() - config.settings.daysInHistogram)
date.toISOString().split('T')[0]
const cleanUpDate = date.toISOString().split('T')[0]
Object.keys(stateMonitors.monitors[monitor].checks).map((checkDay) => {
if (checkDay < cleanUpDate) {
delete stateMonitors.monitors[monitor].checks[checkDay]
}
})
})
// sanity check + if good save the KV
if (configMonitors.length === Object.keys(stateMonitors.monitors).length) {
await saveKVMonitors(kvMonitorsKey, stateMonitors)
} }
}) })
.catch((e) => console.log(e)) .catch((e) => console.log(e))

View File

@ -30,7 +30,9 @@ export default function MonitorCard({ key, monitor, data }) {
</div> </div>
</div> </div>
)} )}
<a href={monitor.url} target="_blank"><div className="text-xl">{monitor.name}</div></a> <a href={monitor.url} target="_blank">
<div className="text-xl">{monitor.name}</div>
</a>
</div> </div>
<MonitorStatusLabel kvMonitor={data} /> <MonitorStatusLabel kvMonitor={data} />
</div> </div>

View File

@ -0,0 +1,17 @@
const locations = {
WAW: 'Warsaw',
SCL: 'Santiago de Chile',
MEL: 'Melbourne',
SIN: 'Singapore',
}
export default function MonitorDayAverage({ location, avg }) {
return (
<>
<br />
<small>
{locations[location] || location}: {avg}ms
</small>
</>
)
}

View File

@ -1,4 +1,6 @@
import React from 'react'
import config from '../../config.yaml' import config from '../../config.yaml'
import MonitorDayAverage from './monitorDayAverage'
export default function MonitorHistogram({ monitorId, kvMonitor }) { export default function MonitorHistogram({ monitorId, kvMonitor }) {
// create date and set date - daysInHistogram for the first day of the histogram // create date and set date - daysInHistogram for the first day of the histogram
@ -43,10 +45,10 @@ export default function MonitorHistogram({ monitorId, kvMonitor }) {
kvMonitor.checks.hasOwnProperty(dayInHistogram) && kvMonitor.checks.hasOwnProperty(dayInHistogram) &&
Object.keys(kvMonitor.checks[dayInHistogram].res).map((key) => { Object.keys(kvMonitor.checks[dayInHistogram].res).map((key) => {
return ( return (
<> <MonitorDayAverage
<br /> location={key}
{key}: {kvMonitor.checks[dayInHistogram].res[key].a}ms avg={kvMonitor.checks[dayInHistogram].res[key].a}
</> />
) )
})} })}
</div> </div>