Next.js lançou instrumentation.ts na versão 13.4 e estabilizou na 15. É a forma oficial e suportada de acoplar código de monitoramento ao seu servidor Next.js. Se você está colocando Next.js em produção e não usa, ou está sem telemetria ou está pagando por um setup mais complicado do que precisa.

O que é instrumentation.ts

instrumentation.ts é um arquivo especial que mora na raiz do seu projeto Next.js. Next.js procura por ele no boot do servidor e chama sua função register exportada uma única vez, antes de qualquer request ser tratado.

// instrumentation.ts
export async function register() {
  // Isso roda uma vez, no server, no boot
}

Esse é todo o contrato. O que você colocar em register() roda no runtime do server antes do tráfego chegar nas suas rotas. É o lugar certo pra inicializar SDKs de monitoramento, registrar instrumentações OpenTelemetry, configurar loggers, e validar configuração de ambiente antes de servir tráfego.

Como habilitar

No Next.js 15 está habilitado por padrão. Só crie o arquivo na raiz do projeto:

// instrumentation.ts
export async function register() {
  console.log('Server booted at', new Date().toISOString())
}

O que você pode interceptar

Padrão 1: Auto-instrumentação OpenTelemetry

// instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { registerOTel } = await import('@vercel/otel')
    registerOTel({ serviceName: 'my-nextjs-app' })
  }
}

O dynamic import é intencional — garante que módulos só-Node não sejam bundleados pro runtime Edge.

Padrão 2: Error tracking com onRequestError

Next.js 15 adicionou um export onRequestError. Esse hook dispara quando um erro server-side é lançado de um route handler, server action, server component ou middleware.

export async function onRequestError(err, request, context) {
  console.error('Server error:', {
    path: request.path,
    route: context.routePath,
    message: err.message,
  })
}

Construindo um hook básico de monitoramento manualmente

// instrumentation.ts
export async function register() {
  console.log('Monitoring initialized')
}

export async function onRequestError(err, request, context) {
  const payload = {
    timestamp: new Date().toISOString(),
    message: err.message,
    stack: err.stack,
    route: context.routePath,
    method: request.method,
  }
  fetch(process.env.MONITORING_WEBHOOK_URL!, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(payload),
  }).catch(() => {})
}

Cerca de 20 linhas. Não é elegante — sem grouping, rate limiting, dashboards, nem alerting — mas funciona.

Por que uma ferramenta dedicada economiza tempo

O exemplo mínimo funciona para "erros caem num webhook". No momento que você quer qualquer uma destas coisas, o line count explode: agrupamento de erros, rate limiting, dashboards, cálculo de P50/P95/P99, alerting (Slack, email, WhatsApp), checks de uptime externos, monitoramento multi-região, suporte a source maps. Cada um é de alguns dias a uma semana de trabalho de engenharia.

Exemplo com Nurbak Watch

// instrumentation.ts
import { initWatch } from '@nurbak/watch'

export async function register() {
  initWatch({
    apiKey: process.env.NURBAK_WATCH_KEY,
    sampleRate: 1.0,
    ignoreRoutes: ['/api/health'],
  })
}

export const onRequestError = async (err, request, context) => {
  const { reportError } = await import('@nurbak/watch')
  reportError(err, { request, context })
}

Isso lida com monitoramento de uptime, tracking de latência interna, taxas de erro e alerting. Auto-descobre cada rota API no seu app.

Erros comuns

  • Importar módulos Node no topo do arquivo. Use dynamic await import() guardado por process.env.NEXT_RUNTIME === 'nodejs'.
  • Fazer trabalho async que bloqueia register(). Deixa cold starts mais lentos.
  • Deixar o monitoramento lançar exceções. Embrulhe em try/catch.
  • Esquecer onRequestError. register roda uma vez, onRequestError roda por erro.
  • Enviar PII em payloads de erro. Limpe cookies, auth headers e bodies antes de forwardar externamente.

Conclusão

instrumentation.ts é a resposta certa para monitoramento Next.js. Substitui os APM agents tradicionais, funciona em serverless e te dá um único lugar pra conectar tudo. Se suas necessidades são simples, construa manual em 20-50 linhas. Se precisa de algo além de reporte básico de erros, use uma ferramenta dedicada.

Experimente o Nurbak Watch:comece grátis — 5 linhas em instrumentation.ts, 3 endpoints, sem cartão.

Artigos relacionados