-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init * Add gitignore, .dev.vars.example, and check in migration files * Update wrangler in all package.json * Update uptime-monitor package.json * Remove typescript language server from example deps * Update cloudflare workers types * Code cleanup * Remove honc-hatch comment * Add a few notes and a format command to the uptime-monitor * Update readme --------- Co-authored-by: Micha 'mies' Hernandez van Leuffen <[email protected]> Co-authored-by: Brett Beutell <[email protected]>
- Loading branch information
1 parent
c7392d4
commit 23f4d46
Showing
28 changed files
with
1,094 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
"db:migrate": "drizzle-kit migrate", | ||
"db:setup": "npm run db:generate && npm run db:migrate", | ||
"db:studio": "drizzle-kit studio", | ||
"fiberplane": "npx @fiberplane/studio@canary", | ||
"fiberplane": "npx @fiberplane/studio@latest", | ||
"format": "biome check . --write" | ||
}, | ||
"dependencies": { | ||
|
@@ -22,8 +22,7 @@ | |
"drizzle-kit": "^0.28.1", | ||
"tsx": "^4.19.2", | ||
"typescript": "^5.5.4", | ||
"typescript-language-server": "^4.3.3", | ||
"wrangler": "3.92.0" | ||
"wrangler": "^3.95.0" | ||
}, | ||
"packageManager": "[email protected]+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Connect to local fiberplane instance | ||
FPX_ENDPOINT=http://localhost:8788/v1/traces |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Normally you don't ignore this file, but it's nice to ignore it for the examples | ||
.fpxconfig | ||
|
||
# prod | ||
dist/ | ||
|
||
# deps | ||
node_modules/ | ||
.wrangler | ||
|
||
# env | ||
.env | ||
.env.production | ||
.dev.vars | ||
.prod.vars | ||
|
||
# misc | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
## 🪿 Website Uptime Monitor | ||
|
||
A serverless website monitoring application built with the HONC stack (Hono, OpenTelemetry, and Cloudflare). This application allows you to monitor the uptime of websites by performing periodic health checks and storing the results in a D1 database. | ||
|
||
### Features | ||
|
||
- Monitor multiple websites simultaneously | ||
- Configurable check intervals per website | ||
- Track response times and HTTP status codes | ||
- Calculate uptime percentages | ||
- RESTful API for managing monitored websites | ||
- Simple web interface to view monitored sites | ||
|
||
### Technology Stack | ||
|
||
- **Hono**: Lightweight web framework for Cloudflare Workers | ||
- **D1**: Cloudflare's serverless SQL database | ||
- **Drizzle ORM**: Type-safe database toolkit | ||
- **Durable Objects**: For managing persistent monitoring schedules | ||
- **OpenTelemetry**: For observability and monitoring | ||
|
||
### Getting Started | ||
|
||
[D1](https://developers.cloudflare.com/d1/) is Cloudflare's serverless SQL database. Running this application involves two key steps: first, setting up the project locally, and second, deploying it in production. | ||
|
||
### Project Structure | ||
|
||
```# | ||
├── src | ||
│ ├── index.tsx # Hono app entry point | ||
│ └── db | ||
│ └── schema.ts # Database schema | ||
├── .dev.vars.example # Example .dev.vars file | ||
├── .prod.vars.example # Example .prod.vars file | ||
├── seed.ts # Optional script to seed the db | ||
├── drizzle.config.ts # Drizzle configuration | ||
├── package.json | ||
├── tsconfig.json # TypeScript configuration | ||
└── wrangler.toml # Cloudflare Workers configuration | ||
``` | ||
|
||
### Commands for local development | ||
|
||
Create a `.dev.vars` file from the example file: | ||
|
||
```sh | ||
cp .dev.vars.example .dev.vars | ||
``` | ||
|
||
Run the migrations and (optionally) seed the database: | ||
|
||
```sh | ||
# this is a convenience script that runs db:touch, db:generate, db:migrate, and db:seed | ||
npm run db:setup | ||
``` | ||
|
||
Run the development server: | ||
|
||
```sh | ||
npm run dev | ||
``` | ||
|
||
As you iterate on the database schema, you'll need to generate a new migration file and apply it like so: | ||
|
||
```sh | ||
npm run db:generate | ||
npm run db:migrate | ||
``` | ||
|
||
### Commands for deployment | ||
|
||
Before deploying your worker to Cloudflare, ensure that you have a running D1 instance on Cloudflare to connect your worker to. | ||
|
||
You can create a D1 instance by navigating to the `Workers & Pages` section and selecting `D1 SQL Database.` | ||
|
||
Alternatively, you can create a D1 instance using the CLI: | ||
|
||
```sh | ||
npx wrangler d1 create <database-name> | ||
``` | ||
|
||
After creating the database, update the `wrangler.toml` file with the database id. | ||
|
||
```toml | ||
[[d1_databases]] | ||
binding = "DB" | ||
database_name = "uptime-d1-database" | ||
database_id = "<database-id-you-just-created>" | ||
migrations_dir = "drizzle/migrations" | ||
``` | ||
|
||
Include the following information in a `.prod.vars` file: | ||
|
||
```sh | ||
CLOUDFLARE_D1_TOKEN="" # An API token with D1 edit permissions. You can create API tokens from your Cloudflare profile | ||
CLOUDFLARE_ACCOUNT_ID="" # Find your Account id on the Workers & Pages overview (upper right) | ||
CLOUDFLARE_DATABASE_ID="" # Find the database ID under workers & pages under D1 SQL Database and by selecting the created database | ||
``` | ||
|
||
If you haven’t generated the latest migration files yet, run: | ||
```shell | ||
npm run db:generate | ||
``` | ||
|
||
Afterwards, run the migration script for production: | ||
```shell | ||
npm run db:migrate:prod | ||
``` | ||
|
||
Change the name of the project in `wrangler.toml` if you want to, but for now it is: | ||
|
||
```toml | ||
name = "uptime-monitor" | ||
``` | ||
|
||
Finally, deploy your worker | ||
|
||
```shell | ||
npm run deploy | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", | ||
"extends": ["../../biome.jsonc"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import fs from "node:fs"; | ||
import path from "node:path"; | ||
import { config } from "dotenv"; | ||
import { defineConfig } from "drizzle-kit"; | ||
|
||
let dbConfig: ReturnType<typeof defineConfig>; | ||
if (process.env.ENVIROMENT === "production") { | ||
config({ path: "./.prod.vars" }); | ||
dbConfig = defineConfig({ | ||
schema: "./src/db/schema.ts", | ||
out: "./drizzle/migrations", | ||
dialect: "sqlite", | ||
driver: "d1-http", | ||
dbCredentials: { | ||
accountId: process.env.CLOUDFLARE_ACCOUNT_ID ?? "", | ||
databaseId: process.env.CLOUDFLARE_DATABASE_ID ?? "", | ||
token: process.env.CLOUDFLARE_D1_TOKEN ?? "", | ||
}, | ||
}); | ||
} else { | ||
config({ path: "./.dev.vars" }); | ||
const localD1DB = getLocalD1DB(); | ||
if (!localD1DB) { | ||
process.exit(1); | ||
} | ||
|
||
dbConfig = defineConfig({ | ||
schema: "./src/db/schema.ts", | ||
out: "./drizzle/migrations", | ||
dialect: "sqlite", | ||
dbCredentials: { | ||
url: localD1DB, | ||
}, | ||
}); | ||
} | ||
|
||
export default dbConfig; | ||
|
||
function getLocalD1DB() { | ||
try { | ||
const basePath = path.resolve(".wrangler"); | ||
const files = fs | ||
.readdirSync(basePath, { encoding: "utf-8", recursive: true }) | ||
.filter((f) => f.endsWith(".sqlite")); | ||
|
||
// In case there are multiple .sqlite files, we want the most recent one. | ||
files.sort((a, b) => { | ||
const statA = fs.statSync(path.join(basePath, a)); | ||
const statB = fs.statSync(path.join(basePath, b)); | ||
return statB.mtime.getTime() - statA.mtime.getTime(); | ||
}); | ||
const dbFile = files[0]; | ||
|
||
if (!dbFile) { | ||
throw new Error(`.sqlite file not found in ${basePath}`); | ||
} | ||
|
||
const url = path.resolve(basePath, dbFile); | ||
|
||
return url; | ||
} catch (err) { | ||
if (err instanceof Error) { | ||
console.log(`Error resolving local D1 DB: ${err.message}`); | ||
} else { | ||
console.log(`Error resolving local D1 DB: ${err}`); | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
examples/uptime-monitor/drizzle/migrations/0000_chief_wrecking_crew.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
CREATE TABLE `uptime_checks` ( | ||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, | ||
`websiteId` integer NOT NULL, | ||
`timestamp` text NOT NULL, | ||
`status` integer, | ||
`responseTime` integer, | ||
`isUp` integer NOT NULL, | ||
FOREIGN KEY (`websiteId`) REFERENCES `websites`(`id`) ON UPDATE no action ON DELETE no action | ||
); | ||
--> statement-breakpoint | ||
CREATE TABLE `websites` ( | ||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, | ||
`url` text NOT NULL, | ||
`name` text NOT NULL, | ||
`checkInterval` integer NOT NULL, | ||
`createdAt` text NOT NULL | ||
); |
Oops, something went wrong.