import { Resource, Tracer } from "@effect/opentelemetry";
import { trace } from "@opentelemetry/api";
import { Context, Effect, Layer, ManagedRuntime } from "effect";
const getParentSpan = () => {
const span = trace.getActiveSpan();
return span && Tracer.makeExternalSpan(span.spanContext());
};
const effectWithActiveSpan = <A, E, R>(effect: Effect.Effect<A, E, R>) => {
const parent = getParentSpan();
return parent
? effect.pipe(Effect.withParentSpan(parent))
: effect.pipe(Effect.withSpan("orphaned"));
};
const make = Effect.gen(function* () {
yield* Effect.logInfo("Executed once when layers are built");
return {
doSomething: () =>
Effect.gen(function* () {
yield* Effect.logInfo("Executed on every request");
return;
}).pipe(Effect.withSpan("ON EVERY REQUEST - 3")),
};
}).pipe(Effect.withSpan("ON FIRST REQUEST ONLY - 3")); // creates a span in a different trace
class MyService extends Context.Tag("MyService")<
MyService,
Effect.Effect.Success<typeof make>
>() {
static Live = Layer.effect(this, make).pipe(
Layer.withSpan("ON FIRST REQUEST ONLY - 2"), // does not create a span
);
}
const program = () =>
Effect.gen(function* () {
const myService = yield* MyService;
return yield* myService.doSomething();
}).pipe(Effect.withSpan("ON EVERY REQUEST - 2"));
const TracingLive = Layer.provide(
Tracer.layerGlobal,
Resource.layer({ serviceName: "test" }),
);
const MainLayer = MyService.Live.pipe(
Layer.provide(TracingLive),
Layer.withSpan("ON FIRST REQUEST ONLY - 1"), // does not create a span
);
const managedRuntime = ManagedRuntime.make(MainLayer);
export async function POST() {
await program().pipe(
Effect.withSpan("ON EVERY REQUEST - 1"),
effectWithActiveSpan,
managedRuntime.runPromiseExit,
);
return new Response(null);
}
import { Resource, Tracer } from "@effect/opentelemetry";
import { trace } from "@opentelemetry/api";
import { Context, Effect, Layer, ManagedRuntime } from "effect";
const getParentSpan = () => {
const span = trace.getActiveSpan();
return span && Tracer.makeExternalSpan(span.spanContext());
};
const effectWithActiveSpan = <A, E, R>(effect: Effect.Effect<A, E, R>) => {
const parent = getParentSpan();
return parent
? effect.pipe(Effect.withParentSpan(parent))
: effect.pipe(Effect.withSpan("orphaned"));
};
const make = Effect.gen(function* () {
yield* Effect.logInfo("Executed once when layers are built");
return {
doSomething: () =>
Effect.gen(function* () {
yield* Effect.logInfo("Executed on every request");
return;
}).pipe(Effect.withSpan("ON EVERY REQUEST - 3")),
};
}).pipe(Effect.withSpan("ON FIRST REQUEST ONLY - 3")); // creates a span in a different trace
class MyService extends Context.Tag("MyService")<
MyService,
Effect.Effect.Success<typeof make>
>() {
static Live = Layer.effect(this, make).pipe(
Layer.withSpan("ON FIRST REQUEST ONLY - 2"), // does not create a span
);
}
const program = () =>
Effect.gen(function* () {
const myService = yield* MyService;
return yield* myService.doSomething();
}).pipe(Effect.withSpan("ON EVERY REQUEST - 2"));
const TracingLive = Layer.provide(
Tracer.layerGlobal,
Resource.layer({ serviceName: "test" }),
);
const MainLayer = MyService.Live.pipe(
Layer.provide(TracingLive),
Layer.withSpan("ON FIRST REQUEST ONLY - 1"), // does not create a span
);
const managedRuntime = ManagedRuntime.make(MainLayer);
export async function POST() {
await program().pipe(
Effect.withSpan("ON EVERY REQUEST - 1"),
effectWithActiveSpan,
managedRuntime.runPromiseExit,
);
return new Response(null);
}