1/// <reference types="@cloudflare/workers-types" />
2
3import { DurableObject } from "cloudflare:workers";
4
5// Minimal OTLP "collector" fixture for AWS/Lambda/Telemetry.test.ts. OTLP/HTTP JSON
6// posts to /v1/{traces,logs,metrics} are appended to a Durable Object so
7// the test can read everything back from any isolate via GET /collected.
8export class OtelSink extends DurableObject {
9 async add(entry: unknown) {
10 const items = (await this.ctx.storage.get<unknown[]>("items")) ?? [];
11 items.push(entry);
12 await this.ctx.storage.put("items", items);
13 }
14
15 async list() {
16 return (await this.ctx.storage.get<unknown[]>("items")) ?? [];
17 }
18}
19
20export default {
21 async fetch(request: Request, env: any): Promise<Response> {
22 const url = new URL(request.url);
23 const sink = env.SINK.get(env.SINK.idFromName("collector"));
24 if (request.method === "POST" && url.pathname.startsWith("/v1/")) {
25 // Record every push, even an unparseable one, so the test can tell
26 // "export never sent" apart from "export sent but malformed".
27 const raw = await request.text();
28 let payload: unknown;
29 try {
30 payload = JSON.parse(raw);
31 } catch {
32 payload = { parseError: true, raw: raw.slice(0, 1000) };
33 }
34 await sink.add({
35 signal: url.pathname.slice("/v1/".length),
36 payload,
37 });
38 return Response.json({ partialSuccess: {} });
39 }
40 if (url.pathname === "/collected") {
41 return Response.json({
42 marker: "otel-collector-ok",
43 items: await sink.list(),
44 });
45 }
46 return new Response("otel-collector-ok");
47 },
48};