From 93c069c4197fa199bffc70d4cdb37d4f2f33086b Mon Sep 17 00:00:00 2001 From: lyc8503 Date: Fri, 20 Oct 2023 02:08:56 +0800 Subject: [PATCH] lastIncident logic improve & index error msg --- README.md | 2 +- components/Header.tsx | 12 +++++++----- pages/index.tsx | 23 +++++++++++++++++++---- worker/src/index.ts | 21 ++++++++++++++------- worker/wrangler.toml | 2 +- 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5c5ad01..538d676 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Another **serverless (and free!)** uptime monitoring & status page on Cloudflare ## ⭐Features - **Opensource** & Easy to deploy (in 10 minutes without local tools) & Free -- Up to **2-minute** interval check on free plan (Up to 1-min on paid Workers plan) +- Up to 50 **2-minute** interval check on free plan (Up to unlimited 1-min on paid Workers plan) - Monitoring for **HTTP/HTTPS/TCP port** - Show 90-day uptime history and uptime percentage - Show all incident history & detailed timeline diff --git a/components/Header.tsx b/components/Header.tsx index cfc5870..1b7f208 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,7 +1,5 @@ import { useState } from 'react'; -import { Container, Group, Burger } from '@mantine/core'; -import { useDisclosure } from '@mantine/hooks'; -import { MantineLogo } from '@mantine/ds'; +import { Container, Group, Text } from '@mantine/core'; import classes from '@/styles/Header.module.css'; const links = [ @@ -12,7 +10,6 @@ const links = [ ]; export default function Header() { - const [opened, { toggle }] = useDisclosure(false); const [active, setActive] = useState(links[0].link); const items = links.map((link) => ( @@ -33,7 +30,12 @@ export default function Header() { return (
- +
+ + 🕒 + UptimeFlare + +
{items} diff --git a/pages/index.tsx b/pages/index.tsx index 95afc44..b5cd554 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -9,6 +9,7 @@ import config from '@/uptime.config' import OverallStatus from '@/components/OverallStatus' import Header from '@/components/Header' import MonitorList from '@/components/MonitorList' +import { Center, Text } from '@mantine/core' export const runtime = 'experimental-edge' const inter = Inter({ subsets: ['latin'] }) @@ -23,9 +24,23 @@ export default function Home({ state }: { state: MonitorState }) {
- - - {/*

{JSON.stringify(state)}

*/} + + { + state === undefined ? + ( +
+ + Monitor State is not defined now, please check your worker's status and KV binding! + +
+ ) : + ( +
+ + +
+ ) + }
) @@ -34,7 +49,7 @@ export default function Home({ state }: { state: MonitorState }) { export async function getServerSideProps() { const { UPTIMEFLARE_STATE } = process.env as unknown as { UPTIMEFLARE_STATE: KVNamespace } - const state = await UPTIMEFLARE_STATE.get('state', 'json') as unknown as MonitorState + const state = await UPTIMEFLARE_STATE?.get('state', 'json') as unknown as MonitorState return { props: { state } } } diff --git a/worker/src/index.ts b/worker/src/index.ts index 4aa8a93..412d091 100644 --- a/worker/src/index.ts +++ b/worker/src/index.ts @@ -23,12 +23,11 @@ async function getStatus(monitor: MonitorTarget): Promise<{ ping: number; up: bo try { const [hostname, port] = monitor.target.split(":") - // Write "PING" and read response + // Write "PING\n" const socket = connect({ hostname: hostname, port: Number(port) }) const reader = socket.readable.getReader() const writer = socket.writable.getWriter() await writer.write(new TextEncoder().encode("PING\n")) - await reader.read() // The read here is necessary to actually test the connection, however it may hang if the server doesn't respond await socket.close() // TODO: should throw an error here but it doesn't? @@ -109,35 +108,43 @@ export default { status.up ? state.overallUp++ : state.overallDown++ // Update incidents - let incidentList = state.incident[monitor.id] || [] + + // Create a dummy incident to store the start time of the monitoring and simplify logic + state.incident[monitor.id] = state.incident[monitor.id] || [ + { + start: [currentTimeSecond], + end: currentTimeSecond, + error: ['dummy'] + } + ] + // Then lastIncident here must not be undefined const lastIncident = incidentList.slice(-1)[0] const timeString = new Date().toLocaleString(config.dateLocale, { timeZone: config.timezone }) if (status.up) { // Current status is up // close existing incident if any - if (lastIncident && lastIncident.end === undefined) { + if (lastIncident.end === undefined) { lastIncident.end = currentTimeSecond await config.callback(`✔️${monitor.name} came back up at ${timeString} after ${Math.round((lastIncident.end - lastIncident.start.slice(-1)[0]) / 60)} minutes of downtime`) } } else { // Current status is down // open new incident if not already open - if (lastIncident === undefined || lastIncident?.end !== undefined) { + if (lastIncident.end !== undefined) { incidentList.push({ start: [currentTimeSecond], end: undefined, error: [status.err] }) await config.callback(`❌${monitor.name} went down at ${timeString} with error ${status.err}`) - } else if (lastIncident && lastIncident.end === undefined && lastIncident.error.slice(-1)[0] !== status.err) { + } else if (lastIncident.end === undefined && lastIncident.error.slice(-1)[0] !== status.err) { // append if the error message changes lastIncident.start.push(currentTimeSecond) lastIncident.error.push(status.err) await config.callback(`❌${monitor.name} is still down at ${timeString} with error ${status.err}`) } } - state.incident[monitor.id] = incidentList // append to latency data let latencyLists = state.latency[monitor.id] || { diff --git a/worker/wrangler.toml b/worker/wrangler.toml index 1d408af..d9f3678 100644 --- a/worker/wrangler.toml +++ b/worker/wrangler.toml @@ -3,7 +3,7 @@ main = "src/index.ts" compatibility_date = "2023-05-15" kv_namespaces = [ - { binding = "UPTIMEFLARE_STATE", id = "30a3733511a246e395ab99ee6a8dceb7" } + { binding = "UPTIMEFLARE_STATE", id = "ff7ab44866d746aaa19f2225e464ad3e" } ] [triggers]