OpenTelemetry — monitoring va tracing
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'lanadispan.end()— har doim,finallyda
[!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.