mirror of
https://github.com/tormachris/cf-workers-status-page.git
synced 2024-11-23 22:45:43 +01:00
chore(perf): save only failed days to KV storage
This commit is contained in:
parent
c3af9db11a
commit
541bdace4b
56
config.yaml
56
config.yaml
@ -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
|
||||
|
@ -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>
|
||||
<div className="black-text">
|
||||
checked {Math.round((Date.now() - kvLastUpdate) / 1000)} sec ago
|
||||
</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) => {
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,29 +34,32 @@ 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)
|
||||
}
|
||||
|
||||
if (!newMetadata.operational) {
|
||||
// try to get failed daily status first as KV read is cheaper than write
|
||||
const kvFailedDayStatusKey = 'h_' + monitor.id + '_' + getDate()
|
||||
const kvFailedDayStatus = await getKV(kvFailedDayStatusKey)
|
||||
await setKV('s_' + monitor.id, null, newMetadata)
|
||||
}
|
||||
|
||||
// write if not found
|
||||
if (!kvFailedDayStatus) {
|
||||
console.log('Saving new failed daily status..')
|
||||
await setKV(kvFailedDayStatusKey, null)
|
||||
}
|
||||
// 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
|
||||
if (!kvFailedDayStatus) {
|
||||
console.log('Saving new failed daily status..')
|
||||
await setKV(kvFailedDayStatusKey, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 = [
|
||||
{
|
||||
type: 'section',
|
||||
text: {
|
||||
type: 'mrkdwn',
|
||||
text: `Some monitor is now in :this: status`,
|
||||
export async function notifySlack(monitor, newMetadata) {
|
||||
const payload = {
|
||||
attachments: [
|
||||
{
|
||||
color: newMetadata.operational ? '#36a64f' : '#f2c744',
|
||||
blocks: [
|
||||
{
|
||||
type: 'section',
|
||||
text: {
|
||||
type: 'mrkdwn',
|
||||
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' },
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user