TypeScript Cloudflare Worker that imports daily analytics logs from Cloudflare R2 into PostgreSQL.
- Cloudflare Worker runtime with built-in cron scheduling.
- Scheduled import every day at
01:00 UTC. - Manual import endpoint with optional
force=truereimport mode. - Dynamic table creation and schema evolution by
dataset. - Import status tracking in the
_importtable.
- Node.js 22 LTS (recommended).
- Cloudflare account with Workers enabled.
- R2 bucket containing files named
YYYY-MM-DD.json.gz. - PostgreSQL reachable from Workers (Hyperdrive is recommended).
-
Install dependencies:
npm install
-
Update
wrangler.toml:- Set
nameto your worker name. - Set
bucket_nameandpreview_bucket_namein[[r2_buckets]]. - If using Hyperdrive, uncomment and fill the
[[hyperdrive]]block.
- Set
-
Configure database credentials as secrets:
wrangler secret put LOGS_DB_URL
Or provide split variables instead:
LOGS_DB_HOSTLOGS_DB_PORTLOGS_DB_USERNAMELOGS_DB_PASSWORDLOGS_DB_DATABASELOGS_DB_SSLMODE(optional:prefer,require,disable, etc.)
If
LOGS_DB_SSLMODEis not set, the driver uses its default behavior. -
(Recommended) Protect endpoints:
wrangler secret put API_TOKEN
-
Run locally:
npm run dev
npm run devuses Cloudflare remote mode so it reads the real R2 bucket. Usenpm run dev:localif you explicitly want local emulation. -
Deploy:
npm run deploy
GET /healthGET|POST /import?date=YYYY-MM-DD&force=true&timeoutMs=120000dateis optional; defaults to yesterday (UTC).force=truedeletes existing rows for that date and dataset before reimport.timeoutMsis optional and defaults to120000.
GET /diag- probes R2 listing and PostgreSQL connectivity.
- add
?tcp=1to include raw TCP object/string probe details.
GET /list?prefix=
If API_TOKEN is set, pass it as either:
Authorization: Bearer <token>x-api-token: <token>
The cron trigger is configured in wrangler.toml:
[triggers]
crons = ["0 1 * * *"]At each run, the worker imports logs for yesterday (UTC).
Use .dev.vars.example as a template for local development.
If imports appear to hang, check the wrangler dev terminal logs and call /diag.