๐ Next.js Instrumentation ๊ฐ์ด๋: ์๋ฒ ๋ฐ ํด๋ผ์ด์ธํธ ๊ด์ธก์ฑ ์ค์
๐ Next.js Instrumentation ๊ฐ์ด๋: ์๋ฒ ๋ฐ ํด๋ผ์ด์ธํธ ๊ด์ธก์ฑ ์ค์
Next.js์ Instrumentation ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง, ์ค๋ฅ ์ถ์ , ๋ก๊น
๋ฑ์ ์ํ ๊ด์ธก์ฑ ๋๊ตฌ๋ฅผ ํตํฉํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
์ด๋ฅผ ํตํด ์๋ฒ์ ํด๋ผ์ด์ธํธ์์ ๋ฐ์ํ๋ ๋ค์ํ ์ด๋ฒคํธ๋ฅผ ์ถ์ ํ๊ณ ๋ถ์ํ ์ ์์ต๋๋ค.
๐ ํ์ผ ๊ตฌ์ฑ ๋ฐ ์์น
1. instrumentation.ts ๋๋ instrumentation.js
- ์์น: ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํ ๋ฆฌ ๋๋ src/ ํด๋ ๋ด๋ถ
- ์ฉ๋: ์๋ฒ ์ธก ๊ด์ธก์ฑ ๋๊ตฌ ์ด๊ธฐํ ๋ฐ ์ค์
- ํ์ ํจ์: register ํจ์
// instrumentation.ts
import { registerOTel } from '@vercel/otel';
export function register() {
registerOTel('next-app');
}
์ฐธ๊ณ :
instrumentation ํ์ผ์ app/ ๋๋ pages/ ๋๋ ํ ๋ฆฌ ๋ด๋ถ๊ฐ ์๋ ๋ฃจํธ์ ์์นํด์ผ ํฉ๋๋ค.
src/ ํด๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํด๋น ํด๋ ๋ด์ ๋ฐฐ์นํฉ๋๋ค.
2. instrumentation-client.ts ๋๋ instrumentation-client.js
- ์์น: ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํ ๋ฆฌ ๋๋ src/ ํด๋ ๋ด๋ถ
- ์ฉ๋: ํด๋ผ์ด์ธํธ ์ธก ๊ด์ธก์ฑ ๋๊ตฌ ์ด๊ธฐํ ๋ฐ ์ค์
- ํน์ง: ํน์ ํจ์์ export ์์ด ์ฝ๋ ์คํ
// instrumentation-client.ts
console.log('ํด๋ผ์ด์ธํธ ์ธก ๊ด์ธก์ฑ ๋๊ตฌ ์ด๊ธฐํ');
// ์ค๋ฅ ์ถ์ ์ค์
window.addEventListener('error', (event) => {
console.error('์ค๋ฅ ๋ฐ์:', event.error);
});
์ฐธ๊ณ :
์ด ํ์ผ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋ก ํธ์๋ ์ฝ๋๊ฐ ์คํ๋๊ธฐ ์ ์ ๋ก๋๋๋ฏ๋ก, ์ด๊ธฐํ ์ฝ๋๋ ๊ธ๋ก๋ฒ ์ค์ ์ ๋ฐฐ์นํ๊ธฐ์ ์ ํฉํฉ๋๋ค.
โ๏ธ ๋์ ์๋ฆฌ ๋ฐ ์ค์
์๋ฒ ์ธก: register ํจ์
- ํธ์ถ ์์ : ์๋ก์ด Next.js ์๋ฒ ์ธ์คํด์ค๊ฐ ์์๋ ๋ ํ ๋ฒ ํธ์ถ
- ๋น๋๊ธฐ ์ง์: async ํจ์๋ก ์ ์ ๊ฐ๋ฅ
export async function register() {
await import('some-observability-tool');
}
์ฃผ์:
register ํจ์๋ ๋ชจ๋ ๋ฐํ์ ํ๊ฒฝ์์ ํธ์ถ๋๋ฏ๋ก, ํน์ ํ๊ฒฝ(Node.js ๋๋ Edge)์๋ง ํ์ํ ์ฝ๋๋ ์กฐ๊ฑด๋ถ๋ก ๋ก๋ํด์ผ ํฉ๋๋ค.
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation-node');
} else if (process.env.NEXT_RUNTIME === 'edge') {
await import('./instrumentation-edge');
}
}
ํด๋ผ์ด์ธํธ ์ธก: ์ด๊ธฐํ ์ฝ๋
- ์คํ ์์ : ํ๋ก ํธ์๋ ์ฝ๋๊ฐ ์คํ๋๊ธฐ ์ ์ ๋ก๋
- ์ฉ๋: ํผํฌ๋จผ์ค ๋ชจ๋ํฐ๋ง, ์ค๋ฅ ์ถ์ , ๋ถ์ ๋๊ตฌ ์ด๊ธฐํ ๋ฑ
// instrumentation-client.ts
performance.mark('app-init');
// ๋ถ์ ๋๊ตฌ ์ด๊ธฐํ
console.log('๋ถ์ ๋๊ตฌ ์ด๊ธฐํ ์๋ฃ');
๐ OpenTelemetry ํตํฉ ์์
Next.js๋ OpenTelemetry๋ฅผ ํตํ ๊ด์ธก์ฑ ๋๊ตฌ ํตํฉ์ ์ง์ํฉ๋๋ค.
@vercel/otel ํจํค์ง๋ฅผ ํ์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
์ค์น
npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation
์ค์
// instrumentation.ts
import { registerOTel } from '@vercel/otel';
export function register() {
registerOTel('next-app');
}
๐งช ํ ์คํธ ๋ฐ ๋๋ฒ๊น
- ํ๊ฒฝ ๋ณ์ ํ์ธ: process.env.NEXT_RUNTIME์ ํตํด ํ์ฌ ๋ฐํ์ ํ๊ฒฝ(Node.js ๋๋ Edge)์ ํ์ธํ ์ ์์ต๋๋ค.
- ์๋ฌ ์ฒ๋ฆฌ: onRequestError ํจ์๋ฅผ instrumentation.ts ํ์ผ์ ์ ์ํ์ฌ ์๋ฒ ์ธก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
export function onRequestError(error: Error) {
console.error('์๋ฒ ์๋ฌ ๋ฐ์:', error);
}
โ ํ์ฉ ๋ฐฉ์
- ์๋ฒ ๋ก๊น
๋ฐ ์ถ์
- instrumentation.ts์ ์๋ฒ ๋ชจ๋ํฐ๋ง ๋๊ตฌ ์ค์
- console.log๋ฅผ ํตํ ์ค์๊ฐ ์ํ ํ์ธ
- ํด๋ผ์ด์ธํธ ๋ถ์ ๋๊ตฌ ํตํฉ
- Google Analytics ๋๋ Sentry ์ด๊ธฐํ ์ฝ๋ ์ถ๊ฐ
- ์ฑ๋ฅ ๋ฐ์ดํฐ ์์ง์ ์ํ Web Vitals ํ์ฉ
- ์๋ฌ ์ถ์
- onRequestError ํจ์๋ก ์๋ฒ ์๋ฌ๋ฅผ ๊ด๋ฆฌ
- ํด๋ผ์ด์ธํธ ์ธก์์๋ window.addEventListener('error')๋ก ์ค๋ฅ ํฌ์ฐฉ
โ ์์ฝ
๊ตฌ์ฑ ์์ ์ค๋ช
instrumentation.ts | ์๋ฒ ์ธก ๊ด์ธก์ฑ ๋๊ตฌ ์ด๊ธฐํ ๋ฐ ์ค์ |
instrumentation-client.ts | ํด๋ผ์ด์ธํธ ์ธก ๊ด์ธก์ฑ ๋๊ตฌ ์ด๊ธฐํ ๋ฐ ์ค์ |
register ํจ์ | ์๋ฒ ์ธ์คํด์ค ์์ ์ ํธ์ถ๋์ด ์ด๊ธฐํ ์์ ์ํ |
onRequestError ํจ์ | ์๋ฒ ์ธก ์๋ฌ ๋ฐ์ ์ ํธ์ถ๋์ด ์๋ฌ ์ฒ๋ฆฌ ์ํ |
๋ฐํ์ ํ๊ฒฝ ๋ณ์ | process.env.NEXT_RUNTIME์ ํตํด ํ์ธ |
OpenTelemetry ํตํฉ | @vercel/otel ํจํค์ง๋ฅผ ํ์ฉํ์ฌ ๊ฐ๋จ ์ค์ |
Next.js, Instrumentation, ๊ด์ธก์ฑ, OpenTelemetry, ์๋ฒ ๋ชจ๋ํฐ๋ง, ํด๋ผ์ด์ธํธ ๋ชจ๋ํฐ๋ง, ํผํฌ๋จผ์ค ์ถ์ , ์๋ฌ ์ถ์ , ๋ก๊น , ๋ถ์ ๋๊ตฌ, ์๋ฒ ์ด๊ธฐํ, ํด๋ผ์ด์ธํธ ์ด๊ธฐํ