Telemetry: event(env, name, { blobs, doubles }) writes one data point to Workers Analytics Engine (the EVENTS binding) for an event declared in events-schema.ts, which says what every column means and how the dataset is laid out. The fields are named, and typed from the schema, so an event can only be written with exactly the fields it declares; their columns come from the schema, never from the call.
event(env, 'jev.relay', { blobs: { outcome: 'forwarded', colo: 'DFW' }, doubles: { status: 200, upstreamMs: 412, requestBytes: 1830, sectionInS: 3.2, attempt: 0 }, });
A null blob is written as null; a null (or non-finite) double as 0 with
its bit in double1 left clear. Writing never throws into the request:
Analytics Engine writes in the background, and a failure to hand it the
point is logged, not raised. Read it back with nix run .#events
(tools/events/).
18import { EVENTS } from './events-schema';
20export { EVENTS }; 21type Schema = typeof EVENTS; 22export type EventName = keyof Schema; 23export type EventFields<N extends EventName> = { 24 blobs: { [K in keyof Schema[N]['blobs']]: string | null }; 25 doubles: { [K in keyof Schema[N]['doubles']]: number | null }; 26}; 27 28type Column = { column: string }; 29const position = (column: string, kind: 'blob' | 'double') => { 30 const m = new RegExp(`^${kind}(\\d+)$`).exec(column); 31 if (!m) throw new Error(`not a ${kind} column: ${column}`); 32 return Number(m[1]); 33};
The data point for an event, as Analytics Engine takes it.
36export function dataPoint<N extends EventName>(name: N, fields: EventFields<N>): AnalyticsEngineDataPoint { 37 const schema = EVENTS[name] as unknown as { blobs: Record<string, Column>; doubles: Record<string, Column> }; 38 const given = fields as unknown as { blobs: Record<string, string | null>; doubles: Record<string, number | null> }; 39 const blobs: (string | null)[] = []; 40 for (const [field, { column }] of Object.entries(schema.blobs)) blobs[position(column, 'blob') - 1] = given.blobs[field] ?? null; 41 const doubles: number[] = [0]; 42 let known = 0; 43 for (const [field, { column }] of Object.entries(schema.doubles)) { 44 const k = position(column, 'double'); 45 const value = given.doubles[field]; 46 const isKnown = typeof value === 'number' && Number.isFinite(value); 47 doubles[k - 1] = isKnown ? value : 0; 48 if (isKnown) known |= 1 << (k - 2); 49 } 50 doubles[0] = known; 51 return { indexes: [name], blobs, doubles }; 52}
54export function event<N extends EventName>( 55 env: { EVENTS: AnalyticsEngineDataset }, 56 name: N, 57 fields: EventFields<N>, 58): void { 59 try { 60 env.EVENTS.writeDataPoint(dataPoint(name, fields)); 61 } catch (e) { 62 console.error({ event: 'events.write', name, error: (e as Error).message }); 63 } 64}