Effect CommunityEC
Effect Community2y ago
6 replies
nickrttn

Integrating OTel with Next.js Project Using `@vercel/otel` for Enhanced Tracing

This might be a question for effect-beginners-🚀 but this seems to be the Otel focused channel.

I've got a Next.js project using @vercel/otel to set up OTel (automatically instruments parts of Next.js, which is very useful). I'm creating a new layer for attaching to my effects as follows:

import { Resource, Tracer } from '@effect/opentelemetry';
import { Layer } from 'effect';

export const OtelTracingLive = Tracer.layerGlobal.pipe(
  Layer.provide(Resource.layer({ serviceName: 'website/effect' })),
);


This re-uses the trace provider that @vercel/otel has created. That works.

Now, I want to attach the spans that @vercel/otel creates as a parent span to spans in Effect. I can't figure out how to do that though. Effect.withSpan expects a Tracer.ParentSpan tagged value for parent. I can get the active span with trace.getActiveSpan. How should I tag and pass the parent span into Effect.withSpan?

export async function POST(
  req: NextRequest,
  { params }: { params: { projectId: Project['id'] } },
) {
  return DoAThing(params.projectId).pipe(
    Effect.withSpan('DoAThing', {
      attributes: {
        url: req.url,
        projectId: params.projectId,
      },
      parent: "please help"
    }),
    Effect.provideService(NextRequestTag, req),
    Effect.provide(Layer.mergeAll(OtelTracingLive, SupabaseAdminLive)),
    Effect.catchTag('ParseError', (error) => {
      Effect.annotateCurrentSpan('otel.status_code', SpanStatusCode.ERROR);
      Effect.annotateCurrentSpan('error', error);
      return Effect.sync(() => NextResponse.json({ error }, { status: 400 }));
    }),
    Effect.catchAll((error) => {
      Effect.annotateCurrentSpan('otel.status_code', SpanStatusCode.ERROR);
      Effect.annotateCurrentSpan('error', error);
      return Effect.sync(() =>
        NextResponse.json('error' in error ? error : { error }, {
          status: 500,
        }),
      );
    }),
    Effect.runPromise,
  );
}
Was this page helpful?