tools/events

nix run .#events: the Worker's telemetry, read back from Workers Analytics Engine. The Worker writes an event with event() (worker/src/events.ts); what each event's columns mean is worker/src/events-schema.ts, which this reads too, so a query names the same fields the Worker wrote.

nix run .#events                                  every event and its columns
nix run .#events -- jev.relay                     its last 50 rows, last day
nix run .#events -- jev.relay --since 7d --limit 500
nix run .#events -- --sql "SELECT … FORMAT JSON"  any query, sent as is

An event's rows come one JSON object a line, newest first, ready for jq. weight is how many events a row stands for (Analytics Engine samples a busy event): count and average with it, e.g.

nix run .#events -- --sql "SELECT blob1 AS outcome, SUM(_sample_interval) AS calls,
  SUM(_sample_interval * double3) / SUM(_sample_interval) AS avg_upstream_ms
  FROM jevstrudel_events WHERE index1 = 'jev.relay'
  AND bitAnd(toUInt32(double1), 2) > 0 AND timestamp > NOW() - INTERVAL '1' DAY
  GROUP BY outcome FORMAT JSON"

(bitAnd(toUInt32(double1), 2): only rows where double3, upstreamMs, is known; see the layout in events-schema.ts.)

It needs the Cloudflare account (from nix-facts, set by the flake) and the same 1Password item as the deploy, whose token must carry Account Analytics: Read. The token is read per run and never printed. Local development writes nowhere: wrangler dev keeps Analytics Engine local, so only the deployed Worker's events are here, kept for three months.

FileWhat it is
events.mjsThe command.
events.test.mjsIts queries and decoding, against the Worker's own writer.