1
0
mirror of https://github.com/tormachris/cf-workers-status-page.git synced 2024-09-21 05:03:02 +02:00

chore(perf): save only failed days to KV storage

This commit is contained in:
Adam Janis 2020-11-12 18:57:42 +01:00
parent c3af9db11a
commit 541bdace4b
6 changed files with 88 additions and 89 deletions

View File

@ -1,6 +1,7 @@
settings:
title: "Status Page"
logo: logo-192x192.png
url: "https://status-page.eidam.dev" # for Slack messages
logo: logo-192x192.png # image in ./public/ folder
daysInHistogram: 90
allmonitorsOperational: "All Systems Operational"
@ -8,7 +9,9 @@ settings:
monitorLabelOperational: "Operational"
monitorLabelNotOperational: "Not great not terrible"
monitorLabelNoData: "No data"
dayInHistogramNoData: "No data"
dayInHistogramOperational: "All good"
dayInHistogramNotOperational: "Some checks failed"
monitors:
- id: kiwi-com-homepage
@ -71,13 +74,6 @@ monitors:
method: GET
expectStatus: 403
- id: google-com-2
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: cf-workers-status-page-2
name: This Workers Status Page project made public
description: /shrug
@ -114,13 +110,6 @@ monitors:
method: GET
expectStatus: 403
- id: google-com-22
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: cf-workers-status-page-22
name: This Workers Status Page project made public
description: /shrug
@ -146,7 +135,7 @@ monitors:
name: Hello World
url: 'http://cnn.cn/'
method: GET
expectStatus: 200
expectStatus: 201
- id: eidam-dev-333
@ -156,13 +145,6 @@ monitors:
method: GET
expectStatus: 403
- id: google-com-333
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: cf-workers-status-page-333
name: This Workers Status Page project made public
description: /shrug
@ -206,13 +188,6 @@ monitors:
method: GET
expectStatus: 403
- id: 25-google-com
name: Bing.com
description: Bing homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: 25-cf-workers-status-page
name: This Workers Status Page project made public
description: /shrug
@ -251,12 +226,6 @@ monitors:
method: GET
expectStatus: 403
- id: 25-google-com-2
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: 25-cf-workers-status-page-2
name: This Workers Status Page project made public
@ -294,13 +263,6 @@ monitors:
method: GET
expectStatus: 403
- id: 25-google-com-22
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: 25-cf-workers-status-page-22
name: This Workers Status Page project made public
description: /shrug
@ -336,12 +298,6 @@ monitors:
method: GET
expectStatus: 403
- id: 25-google-com-333
name: Google.com
description: Google homepage
url: 'https://www.google.com'
method: GET
expectStatus: 200
- id: 25-cf-workers-status-page-333
name: This Workers Status Page project made public

View File

@ -24,6 +24,8 @@ export async function getEdgeProps() {
if (x.metadata.operational === false) monitorsOperational = false
})
console.log(JSON.stringify(kvMonitorsMap))
// transform KV list to array of failed days
const kvMonitorsFailedDaysArray = kvMonitorsFailedDays.map(x => {
return x.name
@ -79,9 +81,13 @@ export default function Index({
? config.settings.allmonitorsOperational
: config.settings.notAllmonitorsOperational}
</div>
{typeof window !== 'undefined' ? (
<div className="black-text">
checked {Math.round((Date.now() - kvLastUpdate) / 1000)} sec ago
</div>
) : (
''
)}
</div>
</div>
{config.monitors.map((monitor, key) => {

View File

@ -15,22 +15,22 @@ export default function MonitorHistogram({
key={`${monitor.id}-histogram`}
className="horizontal flex histogram"
>
{Array.from(Array(config.settings.daysInHistogram + 1).keys()).map(key => {
{Array.from(Array(config.settings.daysInHistogram).keys()).map(key => {
date.setDate(date.getDate() + 1)
const dayInHistory = date.toISOString().split('T')[0]
const dayInHistoryKey = 'h_' + monitor.id + '_' + dayInHistory
const dayInHistogram = date.toISOString().split('T')[0]
const dayInHistogramKey = 'h_' + monitor.id + '_' + dayInHistogram
let bg = ''
let dayInHistoryStatus = 'No data'
let dayInHistogramLabel = config.settings.dayInHistogramNoData
// filter all dates before first check, check the rest
if (kvMonitor && kvMonitor.firstCheck <= dayInHistory) {
if (!kvMonitorsFailedDaysArray.includes(dayInHistoryKey)) {
if (kvMonitor && kvMonitor.firstCheck <= dayInHistogram) {
if (!kvMonitorsFailedDaysArray.includes(dayInHistogramKey)) {
bg = 'green'
dayInHistoryStatus = 'No outage recorded'
dayInHistogramLabel = config.settings.dayInHistogramOperational
} else {
bg = 'orange'
dayInHistoryStatus = 'Some outages'
dayInHistogramLabel = config.settings.dayInHistogramNotOperational
}
}
@ -38,7 +38,7 @@ export default function MonitorHistogram({
<div key={key} className="hitbox">
<div
className={`${bg} bar`}
data-tooltip={`${dayInHistory} - ${dayInHistoryStatus}`}
data-tooltip={`${dayInHistogram} - ${dayInHistogramLabel}`}
/>
</div>
)

View File

@ -1,3 +1,5 @@
import config from '../../config.yaml'
export default function MonitorStatusLabel({ kvMonitorsMap, monitor }) {
let labelColor = 'grey'
let labelText = 'No data'
@ -5,10 +7,10 @@ export default function MonitorStatusLabel({ kvMonitorsMap, monitor }) {
if (typeof kvMonitorsMap[monitor.id] !== 'undefined') {
if (kvMonitorsMap[monitor.id].operational) {
labelColor = 'green'
labelText = 'Operational'
labelText = config.settings.monitorLabelOperational
} else {
labelColor = 'orange'
labelText = 'Not great not terrible'
labelText = config.settings.monitorLabelNotOperational
}
}

View File

@ -1,6 +1,12 @@
import config from '../../config.yaml'
import { setKV, getKVWithMetadata, gcMonitors, getKV } from './helpers'
import {
setKV,
getKVWithMetadata,
gcMonitors,
getKV,
notifySlack,
} from './helpers'
function getDate() {
return new Date().toISOString().split('T')[0]
@ -14,7 +20,7 @@ export async function processCronTrigger(event) {
method: monitor.method || 'GET',
redirect: monitor.followRedirect ? 'follow' : 'manual',
headers: {
'User-Agent': 'cf-worker-status-page',
'User-Agent': config.settings.user_agent || 'cf-worker-status-page',
},
}
@ -28,22 +34,26 @@ export async function processCronTrigger(event) {
firstCheck: kvState.metadata ? kvState.metadata.firstCheck : getDate(),
}
// Write current status if status changed or for first time
// write current status if status changed or for first time
if (
!kvState.metadata ||
kvState.metadata.operational !== newMetadata.operational
) {
console.log('Saving changed state..')
await setKV('s_' + monitor.id, null, newMetadata)
if (typeof SECRET_SLACK_WEBHOOK !== 'undefined') {
// first try to notify Slack in case fetch() or other limit is reached
if (typeof SECRET_SLACK_WEBHOOK_URL !== 'undefined') {
await notifySlack(monitor, newMetadata)
}
await setKV('s_' + monitor.id, null, newMetadata)
}
// write daily status if monitor is not operational
if (!newMetadata.operational) {
// try to get failed daily status first as KV read is cheaper than write
const kvFailedDayStatusKey = 'h_' + monitor.id + '_' + getDate()
console.log(kvFailedDayStatusKey)
const kvFailedDayStatus = await getKV(kvFailedDayStatusKey)
// write if not found
@ -52,7 +62,6 @@ export async function processCronTrigger(event) {
await setKV(kvFailedDayStatusKey, null)
}
}
}
// save last check timestamp
await setKV('lastUpdate', Date.now())

View File

@ -1,3 +1,5 @@
import config from '../../config.yaml'
export async function getMonitors() {
const monitors = await listKV('s_')
return monitors.keys
@ -73,18 +75,42 @@ export async function gcMonitors(config) {
})
}
async function notifySlack(monitor, metadata) {
const blocks = [
export async function notifySlack(monitor, newMetadata) {
const payload = {
attachments: [
{
color: newMetadata.operational ? '#36a64f' : '#f2c744',
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: `Some monitor is now in :this: status`,
text: `Monitor *${monitor.name}* changed status to *${
newMetadata.operational
? config.settings.monitorLabelOperational
: config.settings.monitorLabelNotOperational
}*`,
},
},
]
{
type: 'context',
elements: [
{
type: 'mrkdwn',
text: `${
newMetadata.operational ? ':white_check_mark:' : ':x:'
} \`${monitor.method} ${monitor.url}\` - :eyes: <${
config.settings.url
}|Status Page>`,
},
],
},
],
},
],
}
return fetch(SECRET_SLACK_WEBHOOK_URL, {
body: JSON.stringify({ blocks }),
body: JSON.stringify(payload),
method: 'POST',
headers: { 'Content-Type': 'application/json' },
})