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 porprocess.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.

