1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Telemetry from "@/Telemetry.ts";
3import * as Config from "effect/Config";
4import * as Effect from "effect/Effect";
5import * as Layer from "effect/Layer";
6import { HttpServerRequest } from "effect/http/HttpServerRequest";
7import * as HttpServerResponse from "effect/http/HttpServerResponse";
8import * as Otlp from "effect/observability/Otlp";
9
10/**
11 * Effect-native Worker exercising the *custom exporter* telemetry path:
12 * `Effect.provide(Telemetry.layer(...))` on the Worker's init Effect
13 * replaces the env-driven default with a hand-built OTLP Layer. The Layer
14 * is still built once per event into the request scope, so its exporters
15 * flush when the request scope finalizes.
16 */
17export default class OtelCustomWorker extends Cloudflare.Worker<OtelCustomWorker>()(
18 "OtelCustomWorker",
19 {
20 main: import.meta.url,
21 env: {
22 // Config key must equal the env key — the props re-execute inside
23 // the deployed isolate and re-read the Config from the bound var.
24 COLLECTOR_URL: Config.String("COLLECTOR_URL"),
25 },
26 },
27 Effect.gen(function* () {
28 return {
29 fetch: Effect.gen(function* () {
30 const request = yield* HttpServerRequest;
31 const url = new URL(request.url, "http://x");
32 if (url.pathname === "/work") {
33 yield* Effect.log("custom-work-log").pipe(
34 Effect.withSpan("custom.child-span"),
35 );
36 return yield* HttpServerResponse.json({ marker: "custom-did-work" });
37 }
38 return HttpServerResponse.text("otel-custom-ok");
39 }),
40 };
41 }).pipe(
42 Effect.provide(
43 Telemetry.layer(
44 Layer.unwrap(
45 Effect.gen(function* () {
46 const baseUrl = yield* Config.String("COLLECTOR_URL");
47 return Otlp.layerJson({
48 baseUrl,
49 resource: { serviceName: "otel-custom-test" },
50 });
51 }),
52 ),
53 ),
54 ),
55 ),
56) {}