Next.js Instrumentation 가이드 정리 (App Router)
1. Instrumentation 개요
Instrumentation은 애플리케이션에 모니터링/로깅 도구를 심는(instrument) 작업입니다.
운영 환경에서 성능/동작을 관찰하고, 문제를 더 빨리 디버깅할 수 있게 해줍니다.
Next.js에서는 서버 인스턴스가 시작될 때 1회 실행되는 훅을 제공하고, 이 훅 안에서 OpenTelemetry 같은 도구를 등록하는 방식이 일반적입니다.
2. Step 1: instrumentation.ts|js 파일 만들기 (Convention)
프로젝트 루트에 instrumentation.ts 또는 instrumentation.js 파일을 생성합니다.
src폴더를 쓰는 경우:src/아래에app/,pages/와 같은 레벨에 둡니다.app/또는pages/안에 넣는 것이 아니라 루트(or src 루트) 에 둬야 합니다.pageExtensions로 파일 suffix를 바꾸는 경우,instrumentation파일명도 그 suffix에 맞춰야 합니다.
3. Step 2: register() 함수 export 하기
instrumentation.ts|js에서 register 함수를 export 합니다.
- 이
register()는 새로운 Next.js 서버 인스턴스가 시작될 때 1번 호출됩니다.
예: Next.js + OpenTelemetry + @vercel/otel 조합
// instrumentation.ts
import { registerOTel } from '@vercel/otel'
export function register() {
registerOTel('next-app')
}
4. Examples
4-1) Side effect가 있는 파일 import 하기
“전역 변수 등록”, “초기화 코드 실행”처럼 import 자체의 부작용(side effect)이 목적이라면,
register() 내부에서 import()로 불러오는 방식이 권장됩니다.
// instrumentation.ts
export async function register() {
await import('package-with-side-effect')
}
- 파일 상단에서 전역 import로 넣기보다,
register()안에 모아서 관리하는 게 안전합니다.
4-2) Runtime별 코드 분리하기 (Node.js / Edge)
Next.js는 모든 환경에서 register()를 호출할 수 있으므로,
특정 런타임에서 동작하지 않는 코드는 조건부 import로 분리합니다.
process.env.NEXT_RUNTIME값을 사용해 런타임을 판별합니다.
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation-node')
}
if (process.env.NEXT_RUNTIME === 'edge') {
await import('./instrumentation-edge')
}
}
5. 정리
instrumentation.ts|js는 루트(or src 루트) 에 둡니다.register()는 서버 인스턴스 시작 시 1회 호출되는 초기화 훅입니다.- 부작용 import는
register()안에서import()로 처리하는 패턴이 권장됩니다. - Node/Edge 런타임 차이는
NEXT_RUNTIME으로 분기해 런타임별 파일을 나눕니다.