OpenTelemetry — monitoring va tracing

~15 daq · Next.js · Ilg'or mavzular

Muammodan boshlaylik

Foydalanuvchilar: "Mahsulot sahifasi ba'zan 4 soniya ochiladi". Siz lokal sinab ko'rasiz — 300 ms. Loglarda faqat:

GET /mahsulot/abc 200 4120ms

4 soniya qayerga ketdi? Sahifa render? Baza so'rovi? Tavsiyalar API si? Auth tekshiruvi? Bir nechta so'rov ketma-ket kutildimi? Bitta umumiy raqam muammoni ko'rsatmaydi.


Tracing nima?

Trace — bitta so'rovning ilova ichidagi butun yo'li. U span lardan iborat — har bir span bitta amal va uning davomiyligi:

GET /mahsulot/abc ─────────────────────────────────────── 4120 ms
├── middleware (auth)        ██ 40 ms
├── render route /mahsulot/[id]
│   ├── prisma.mahsulot.findUnique   ███ 60 ms
│   ├── fetch tavsiyalar API         ████████████████████ 3800 ms  ← aybdor
│   └── prisma.sharh.findMany        ██ 45 ms
└── ...

Endi aniq: tashqi tavsiyalar API si sekin, va u qolgan ma'lumot bilan ketma-ket kutilmoqda.

OpenTelemetry (OTel) — trace, metrika va loglarni yig'ish uchun ochiq standart. Bir marta ulaysiz — natijani istalgan tizimga yuborasiz: Jaeger, Grafana Tempo, Honeycomb, Datadog, Sentry, New Relic...


Hayotiy o'xshatma

Posilka kuzatuvi. "Posilka 9 kunda yetib keldi" — hech narsa demaydi. Kuzatuv tarixi esa: "Ombor — 1 kun, bojxona — 6 kun, kuryer — 2 kun". Endi muammo qayerdaligi aniq — bojxona. Trace — so'rovning kuzatuv tarixi.


Next.js da yoqish

Next.js ichida OpenTelemetry qo'llab-quvvatlashi o'rnatilgan — render, fetch, Route Handler, middleware uchun span lar avtomatik yaratiladi.

npm install @vercel/otel @opentelemetry/api
// instrumentation.ts — loyiha ildizida (yoki src/)
import { registerOTel } from '@vercel/otel'

export function register() {
  registerOTel({ serviceName: 'dokon-web' })
}

instrumentation.ts — Next.js server ishga tushganda bir marta chaqiriladi. @vercel/otel Node.js va Edge runtime larida ishlaydi va Vercel da ham, o'z serveringizda ham ishlatiladi.

Qayerga yuborish

# .env — OTLP standart o'zgaruvchilari
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.example.com
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer xxx

Lokal sinash uchun — Jaeger Docker da:

docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

http://localhost:16686 — trace larni vizual ko'rish.


Avtomatik span lar

Span Qachon
[http.method] [next.route] Har bir kiruvchi so'rov
render route (app) /mahsulot/[id] Sahifa render
fetch GET https://... Server dagi har bir fetch
executing api route (app) /api/... Route Handler
generateMetadata Metadata hisoblash
middleware Middleware

Prisma, PostgreSQL, Redis kabi kutubxonalar uchun — ularning OpenTelemetry instrumentatsiya paketlari (masalan, @prisma/instrumentation).


O'z span laringiz

import { trace } from '@opentelemetry/api'

const tracer = trace.getTracer('dokon')

export async function tavsiyalarniHisobla(userId: string) {
  return tracer.startActiveSpan('tavsiyalar.hisoblash', async (span) => {
    try {
      span.setAttribute('user.id', userId)
      const natija = await ogirHisob(userId)
      span.setAttribute('tavsiyalar.soni', natija.length)
      return natija
    } catch (err) {
      span.recordException(err as Error)
      span.setStatus({ code: 2 })    // ERROR
      throw err
    } finally {
      span.end()
    }
  })
}
  • setAttribute — qidirish va filtrlash uchun ma'lumot (user ID, mahsulot ID, natija hajmi)
  • recordException — xato trace ga bog'lanadi
  • span.end() — har doim, finally da

[!WARNING] Atributlarga parol, token, karta raqami, to'liq shaxsiy ma'lumotlarni yozmang — trace lar monitoring tizimida ko'p odamga ko'rinadi va uzoq saqlanadi. ID lar yetarli.


Uchta ustun — observability

Savol Misol
Trace Bu so'rov qayerda vaqt sarfladi? 3800 ms — tavsiyalar API
Metrika Umumiy holat qanday? p95 javob vaqti, xatolar ulushi, RPS
Log Aniq nima bo'ldi? "Tavsiyalar API timeout, userId=7"

Eng kuchli holat — uchalasi trace ID orqali bog'langan: grafikdagi sakrashdan → sekin trace ga → shu so'rov loglariga.

[!TIP] Production da har bir so'rovni trace qilish qimmat bo'lishi mumkin. Sampling — masalan, so'rovlarning 10% i (OTEL_TRACES_SAMPLER=parentbased_traceidratio, OTEL_TRACES_SAMPLER_ARG=0.1). Xatoli va sekin so'rovlarni har doim saqlaydigan sampling ni monitoring tizimingiz qo'llab-quvvatlashi mumkin.


Tez-tez uchraydigan xatolar

1. instrumentation.ts noto'g'ri joyda

app/ ichida — ishlamaydi. Loyiha ildizida yoki src/ da.

2. span.end() ni unutish

Span hech qachon yopilmaydi — trace to'liq emas, xotira sarflanadi.

3. Faqat loglarga tayanish

"So'rov 4 soniya" — sababini ko'rsatmaydi. Trace — qaysi qadam.


Xulosa

Trace — so'rovning to'liq yo'li; span — bitta amal va davomiyligi
OpenTelemetry — ochiq standart, istalgan backend (Jaeger, Tempo, Datadog...)
instrumentation.ts + registerOTel({ serviceName }) — @vercel/otel
Next.js span lari avtomatik: so'rov, render, fetch, Route Handler, middleware
O'z span lar: tracer.startActiveSpan, setAttribute, recordException, end
OTEL_EXPORTER_OTLP_ENDPOINT; lokal — Jaeger
Maxfiy ma'lumot atributlarda yo'q; sampling

Keyingi dars

75-dars: Real loyiha arxitekturasi — papkalar tuzilishi, best practices

Kurs yakuni: o'rganilgan hamma narsani to'g'ri tuzilgan loyihaga birlashtirish.