Capítulo 315 de 456
Next.js já vem instrumentado com OpenTelemetry; habilitar via @vercel/otel no instrumentation.ts envolve automaticamente código como getStaticProps em spans com atributos úteis, sem precisar trocar de provedor de observabilidade depois.
@vercel/otel: pacote que simplifica o setup verboso do OpenTelemetry puro; chamado dentro de register() em instrumentation.ts.NodeSDK diretamente dá mais controle, mas não é compatível com Edge runtime; precisa isolar em instrumentation.node.ts, importado condicionalmente só quando NEXT_RUNTIME === 'nodejs'.NEXT_OTEL_VERBOSE=1: expõe mais spans que os emitidos por padrão, útil pra debug local.NEXT_OTEL_FETCH_DISABLED=1: desliga o span automático de fetch, útil se você já usa outra lib de instrumentação de fetch.@opentelemetry/api, trace.getTracer(...).startActiveSpan(name, async (span) => { ...; span.end() }).[http.method] [next.route]), render de rota, fetch, execução de Route Handler, getServerSideProps, getStaticProps, render de documento (pages), generateMetadata, resolução de componentes/módulos de segmento, e o zero-length span start response.next.*: next.span_name, next.span_type, next.route, next.rsc, next.page (identificador interno usado com layout.ts/page.ts/etc, precisa combinar com next.route pra ser único).import { registerOTel } from '@vercel/otel'
export function register() {
registerOTel({ serviceName: 'next-app' })
}
@vercel/otel.export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation.node.ts')
}
}
const sdk = new NodeSDK({
resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: 'next-app' }),
spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter()),
})
sdk.start()
NodeSDK, isolado do Edge runtime via import condicional.import { trace } from '@opentelemetry/api'
export async function fetchGithubStars() {
return await trace.getTracer('nextjs-example').startActiveSpan('fetchGithubStars', async (span) => {
try {
return await getValue()
} finally {
span.end()
}
})
}
span.end() garantido no finally.| Span | next.span_type | O que representa |
|---|---|---|
[http.method] [next.route] | BaseServer.handleRequest | Request raiz |
render route (app) [next.route] | AppRender.getBodyResult | Render de rota no App Router |
fetch [http.method] [http.url] | AppRender.fetch | Chamada fetch no código |
executing api route (app) [next.route] | AppRouteRouteHandlers.runHandler | Execução de Route Handler |
getServerSideProps [next.route] | Render.getServerSideProps | Execução de getServerSideProps |
getStaticProps [next.route] | Render.getStaticProps | Execução de getStaticProps |
generateMetadata [next.page] | ResolveMetadata.generateMetadata | Geração de metadata |
NodeSDK sem isolar do Edge runtime: NodeSDK não é compatível com Edge; precisa de import condicional via NEXT_RUNTIME.span.end(): sempre chamar dentro de finally pra não deixar span aberto em caso de erro.@vercel/otel cobre a maioria dos casos com setup mínimo; configuração manual só quando precisa de algo que ele não expõe.NEXT_OTEL_VERBOSE=1 e NEXT_OTEL_FETCH_DISABLED=1 são os dois env vars de controle mais usados em debug/produção.register() em instrumentation.ts.