ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

 

๐Ÿ” Next.js์—์„œ OpenTelemetry๋กœ ๊ด€์ธก์„ฑ(Observability) ๊ตฌ์ถ•ํ•˜๊ธฐ

Next.js๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ SSR๊ณผ ๋™์  ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ์„œ๋น„์Šค ๊ตฌ์กฐ์—์„œ ์„ฑ๋Šฅ ์ถ”์ ๊ณผ ์˜ค๋ฅ˜ ์ง„๋‹จ์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด๋•Œ ํ‘œ์ค€ํ™”๋œ ์˜คํ”ˆ์†Œ์Šค์ธ OpenTelemetry๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋กœ๊ทธ, ๋ฉ”ํŠธ๋ฆญ, ํŠธ๋ ˆ์ด์Šค๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ์ˆ˜์ง‘ํ•˜๊ณ  ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


โœ… OpenTelemetry๋ž€?

OpenTelemetry(OTel)๋Š” ๋‹ค์Œ ์„ธ ๊ฐ€์ง€๋ฅผ ํ•˜๋‚˜๋กœ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š” ํ‘œ์ค€ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

  • ๐Ÿ“ˆ ๋ฉ”ํŠธ๋ฆญ (Metrics)
  • ๐Ÿ” ํŠธ๋ ˆ์ด์Šค (Traces)
  • ๐Ÿชต ๋กœ๊ทธ (Logs)

์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ๋„˜๋‚˜๋“œ๋Š” ์š”์ฒญ ํ๋ฆ„์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ ๋ณ‘๋ชฉ๊ณผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์ง€์ ์„ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


โœ… ๊ธฐ๋ณธ ์„ค์ • ๋ฐฉ๋ฒ• (@vercel/otel ์‚ฌ์šฉ)

1. ํŒจํ‚ค์ง€ ์„ค์น˜

npm install @vercel/otel

2. ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— instrumentation.ts ์ƒ์„ฑ

import { registerOTel } from '@vercel/otel';

export function register() {
  registerOTel({ serviceName: 'next-app' });
}

3. next.config.js ์„ค์ •

module.exports = {
  experimental: {
    instrumentationHook: true,
  },
};

instrumentation.ts๋Š” ๋ฐ˜๋“œ์‹œ ๋ฃจํŠธ์— ์žˆ์–ด์•ผ ํ•˜๊ณ , Next.js 14+ ์ด์ƒ๋ถ€ํ„ฐ ์ง€์›๋ฉ๋‹ˆ๋‹ค.


โœ… ๊ณ ๊ธ‰ ์„ค์ • (์ˆ˜๋™ ์„ค์ •)

๋” ์„ธ๋ถ€์ ์ธ ํŠธ๋ ˆ์ด์‹ฑ์ด๋‚˜ ์™ธ๋ถ€ ์ˆ˜์ง‘ ์„œ๋ฒ„ ์—ฐ๋™์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ ์ˆ˜๋™ ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์„ค์น˜

npm install @opentelemetry/sdk-node \
             @opentelemetry/exporter-trace-otlp-http \
             @opentelemetry/resources \
             @opentelemetry/semantic-conventions

์„ค์ • ์˜ˆ์‹œ

import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';

export function register() {
  const sdk = new NodeSDK({
    resource: new Resource({
      [SemanticResourceAttributes.SERVICE_NAME]: 'next-app',
    }),
    traceExporter: new OTLPTraceExporter({
      url: 'http://localhost:4318/v1/traces',
    }),
  });

  sdk.start();
}

โœ… ์ฃผ์š” ์ŠคํŒฌ ๋ชฉ๋ก

๋ฐ˜์‘ํ˜•

Next.js์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ŠคํŒฌ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  • render route (app) /about
  • fetch GET https://api.example.com
  • getServerSideProps /dashboard
  • executing api route /api/user

โœ… ์‚ฌ์šฉ์ž ์ •์˜ ์ŠคํŒฌ ์ถ”๊ฐ€

import { trace } from '@opentelemetry/api';

export default async function handler(req, res) {
  const tracer = trace.getTracer('custom');
  const span = tracer.startSpan('fetch-user-data');

  try {
    await fetchUser();
    res.status(200).json({ ok: true });
  } catch (e) {
    span.recordException(e);
    res.status(500).json({ error: 'fail' });
  } finally {
    span.end();
  }
}

โœ… ์ž๋™ ๊ณ„์ธก

์ž๋™์œผ๋กœ fetch, fs, http ๋“ฑ ์ฃผ์š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณ„์ธกํ•˜๋ ค๋ฉด ๋‹ค์Œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

npm install @opentelemetry/auto-instrumentations-node
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  instrumentations: [getNodeAutoInstrumentations()],
});

โœ… Vercel ํ™˜๊ฒฝ์—์„œ์˜ ํ™œ์šฉ

  • @vercel/otel ์‚ฌ์šฉ ์‹œ, Vercel ํ”Œ๋žซํผ์—์„œ ์†์‰ฝ๊ฒŒ ํ™œ์„ฑํ™” ๊ฐ€๋Šฅ
  • NEXT_OTEL_VERBOSE=1 ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๋””๋ฒ„๊น… ๋กœ๊ทธ ํ™œ์„ฑํ™” ๊ฐ€๋Šฅ

โœ… ์š”์•ฝ

ํ•ญ๋ชฉ ๊ฐ„ํŽธ ์„ค์ • (@vercel/otel) ์ˆ˜๋™ ์„ค์ •

์„ค์ • ๋‚œ์ด๋„ ๋งค์šฐ ์‰ฌ์›€ ๋‹ค์†Œ ๋ณต์žก
Edge ์ง€์› ์—ฌ๋ถ€ O X
์„ธ๋ถ€ ์ œ์–ด ๊ฐ€๋Šฅ์„ฑ ์ œํ•œ์  ๋งค์šฐ ๋†’์Œ
์ž๋™ ๊ณ„์ธก ๊ธฐ๋ณธ ์ œ๊ณต ์ง์ ‘ ์„ค์ • ํ•„์š”
๋ฐฐํฌ ํ”Œ๋žซํผ Vercel ์ตœ์ ํ™” ์–ด๋””์„œ๋“  ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

Next.js, OpenTelemetry, Observability, ๋ฉ”ํŠธ๋ฆญ, ํŠธ๋ ˆ์ด์Šค, ์„œ๋น„์Šค ๋ชจ๋‹ˆํ„ฐ๋ง, ๋กœ๊ทธ ๋ถ„์„, ์„ฑ๋Šฅ ์ตœ์ ํ™”, Vercel, Full Stack Observability


โ€ป ์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค.
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2025/06   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
๊ธ€ ๋ณด๊ด€ํ•จ
๋ฐ˜์‘ํ˜•