Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. process.report: jarayonning hisoboti
- 2.1 Hisobotni olish
- 2.2 Sir xavfi
- 2.3 Qulash paytida avtomatik hisobot
- 3. Ogohlantirishlar va eskirish
- 3.1 Ogohlantirish qayerdan?
- 3.2 O'z eskirish ogohlantirishingiz
- 4. --trace-gc: GC'ning har qadami
- 5. diagnostics_channel: kutubxona ichiga oyna
- 5.1 Muammo
- 5.2 O'z kanalingiz
- 5.3 Node'ning o'z kanallari
- 5.4 Boshlanish, tugash va xato: tracingChannel
- 6. perf_hooks: vaqtni o'lchash
- 6.1 mark va measure
- 6.2 PerformanceObserver va timerify
- 7. Qaysi vosita qachon
- 8. CLI qadami: holat yo'q — tajriba
- 9. Ko'p uchraydigan xatolar
- 9.1 --report-dir papkasi yo'q
- 9.2 Hisobotni sirlar bilan ulashish
- 9.3 Ogohlantirishni o'chirib qo'yish
- 9.4 --report-on-signal Windows'da
- 9.5 Bir martalik o'lchovga ishonish
- 10. Mashqlar
- 1-mashq (oson): bo'sh joylarni to'ldiring
- 2-mashq (o'rta): hisobot xulosasi
- 3-mashq (qiyin): kanalli kutubxona
- 4-mashq: CLI qadami — valyuta ning eskirish ogohlantirishi
- 11. Real ishda
- Xulosa
- Manbalar
Node.js diagnostika: process.report, trace bayroqlari, diagnostics_channel va perf_hooks
Qisqacha: Prodakshnda debugger ulab bo'lmaydi. Buning o'rniga Node'ning o'zi "qora quti" beradi. Asosiysi — jarayonning JSON hisoboti (
process.report): stek, heap, resurslar va muhit.--report-on-fatalerrorva--report-uncaught-exceptionuni qulash paytida o'zi yozadi.--trace-warnings,--trace-deprecationogohlantirish qayerdan kelganini ko'rsatadi,--trace-gc— GC har ishlaganini.diagnostics_channelkutubxona ichidan hodisalarni tashqariga chiqaradi,perf_hooksesa vaqtni o'lchaydi.
Bu darsda
process.reporthisobotini olasiz, bo'limlarini o'qiysiz va undagi sir xavfini bilasiz.- Qulash paytida hisobotni avtomatik yozdirasiz va Windows'dagi ikki tuzoqni chetlab o'tasiz.
- Ogohlantirish va eskirish xabarlarini izi bilan ko'rasiz, o'z eskirish ogohlantirishingizni yozasiz.
--trace-gcqatorini o'qiysiz.diagnostics_channelbilan kutubxona ichini kuzatasiz vaperf_hooksbilan funksiya vaqtini o'lchaysiz.
Oldin bilishingiz kerak: CPU profiling va flamegraph, Memory leak'ni topish, Node'ni debug qilish, Performansni o'lchash.
1. Nega bu kerak?
Node'ni debug qilish darsida kodni to'xtatib, o'zgaruvchilarga qaradingiz. Bu — o'z kompyuteringizda ajoyib. Lekin tasavvur qiling: server tunda soat 3:14 da qulab tushdi. Ertalab qayta ishga tushirilgan, hamma narsa ishlayapti. Nima bo'lgan edi?
Debugger bu yerda yordam bermaydi: qulash allaqachon o'tib ketgan. Kerakli narsa — voqea paytida yozilgan yozuv. Samolyotlardagi "qora quti" kabi: halokatdan keyin u balandlik, tezlik va dvigatel holatini ko'rsatadi.
Node'da shunday bir nechta vosita bor va ularning hammasi o'rnatilgan — paket kerak emas. Ular bir-birini to'ldiradi:
| Savol | Vosita |
|---|---|
| Qulash paytida jarayon qanday holatda edi? | process.report |
| Bu ogohlantirish qayerdan? | --trace-warnings, --trace-deprecation |
| GC qanchalik tez-tez va qancha vaqt ishlaydi? | --trace-gc |
| Kutubxona ichida nima bo'lyapti? | diagnostics_channel |
| Qaysi qism qancha vaqt oladi? | perf_hooks |
2. process.report: jarayonning hisoboti
2.1 Hisobotni olish
Diagnostika hisoboti (diagnostic report) — bitta JSON hujjat: Node versiyasi, operatsion tizim, JS va native stek, heap statistikasi, CPU va xotira sarfi, libuv handle'lari, muhit o'zgaruvchilari. Uni istalgan paytda koddan olsa bo'ladi:
const hisobot = process.report.getReport();
console.log(Object.keys(hisobot).join("\n"));
console.log(typeof hisobot.header.nodejsVersion);Konsolda:
header
javascriptStack
javascriptHeap
nativeStack
resourceUsage
uvthreadResourceUsage
libuv
workers
environmentVariables
sharedObjects
stringHar bo'lim nima beradi:
| Bo'lim | Ichida |
|---|---|
header |
Node versiyasi, OS, CPU'lar, buyruq qatori, vaqt |
javascriptStack |
Xato xabari va JS stek |
javascriptHeap |
Heap hajmi va har maydon (space) bo'yicha |
resourceUsage |
CPU vaqti, maksimal RSS, disk amallari |
libuv |
Ochiq handle'lar: taymerlar, fayllar, soketlar |
environmentVariables |
Hamma muhit o'zgaruvchilari |
Kanon tajribasi (t49-diag.txt, Windows) header dan: nodejsVersion: 'v24.21.0', osName: 'Windows_NT', cpus: 16; libuv da 9 handle, JS stekda 4 qator. glibcVersionRuntime maydoni Windows'da yo'q — u faqat Linux'da bo'ladi (hujjat bo'yicha).
Faylga yozish uchun — process.report.writeReport(). U fayl nomini qaytaradi: report.20261023.141233.3108.0.001.json ko'rinishida (sana, vaqt, PID, tartib raqami).
2.2 Sir xavfi
environmentVariables da hamma muhit o'zgaruvchilari bor. Env va sirlar darsidan eslang: DATABASE_URL, JWT_SECRET, API kalitlari aynan shu yerda yashaydi. Hisobotni issue'ga yoki chatga yuklasangiz — sirlar ham ketadi.
Yechim — --report-exclude-env bayrog'i. Biz sinadik: MAXFIY=sir123 o'zgaruvchisi bilan oddiy hisobotda environmentVariables.MAXFIY — sir123, bayroq bilan esa environmentVariables bo'limi umuman yo'q (undefined). Shunga o'xshash --report-exclude-network tarmoq interfeyslari ma'lumotini olib tashlaydi.
Diqqat: Hisobotni birovga yuborishdan oldin uni oching va qidiring:
KEY,SECRET,TOKEN,PASSWORD,://(ulanish satrlari). Kanondagi hisobot ham shu qadamdan o'tgan.
2.3 Qulash paytida avtomatik hisobot
Asl kuch — hisobotni o'zi yozdirish. Ikki bayroq:
--report-uncaught-exception— ushlanmagan xato bo'lganda;--report-on-fatalerror— V8 halokatli xatosida (masalan, heap tugaganda).
Biz cheksiz massivli dasturni 32 MB limit bilan ishga tushirdik:
node --max-old-space-size=32 --report-on-fatalerror \
--report-dir=hisobot ozish.mjsBirinchi urinishda hisobot yozilmadi:
Failed to open Node.js report file: report.20261023.141223.15508.0.001.json directory: hisobot (errno: 2)Tarjimasi: "hisobot faylini ochib bo'lmadi … papka: hisobot (xato 2)". errno: 2 — "bunday fayl yoki papka yo'q". Node --report-dir papkasini o'zi yaratmaydi. Qulash allaqachon bo'ldi — hisobot esa yo'qoldi. Papkani oldindan yaratgandan keyin:
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
Writing Node.js report to file: report.20261023.141233.3108.0.001.json
Node.js report completedHisobot (21 KB) ichida header.event — Allocation failed - JavaScript heap out of memory, header.trigger — OOMError. JS stek esa Unavailable. — heap tugaganda JS kodi to'xtagan bo'ladi. Ushlanmagan xato hisobotida (--report-uncaught-exception) trigger — Exception, javascriptStack.message — Error: kurs topilmadi, stek qatorlari bilan.
Uchinchi bayroq — --report-on-signal (signal kelganda hisobot). Node yordam matni o'zi aytadi: Windows'da qo'llab-quvvatlanmaydi. Linux'da kill -USR2 <pid> bilan ishlaydi (hujjat bo'yicha; biz sinamadik).
Tekshirib ko'ring: Siz serverga
--report-on-fatalerror --report-dir=/var/log/ilovaqo'shdingiz. Bir hafta o'tib server qulab tushdi, lekin papkada hisobot yo'q. Ikki ehtimoliy sababni ayting.
Javob
(1) Papka yo'q edi — Node uni yaratmaydi va faqat stderr'ga Failed to open Node.js report file deb yozadi. (2) Jarayonning shu papkaga yozish huquqi yo'q. Uchinchi variant ham bor: qulash V8 xatosi emas edi (masalan, process.exit(1) yoki ushlanmagan xato) — --report-on-fatalerror faqat halokatli xatoda ishlaydi, ushlanmagan xato uchun --report-uncaught-exception kerak.
3. Ogohlantirishlar va eskirish
3.1 Ogohlantirish qayerdan?
Node ba'zan stderr'ga ogohlantirish yozadi: MaxListenersExceededWarning, ExperimentalWarning, DeprecationWarning. Muammo: xabar nima bo'lganini aytadi, qayerda — yo'q. Katta loyihada bu satr sizning kodingizdanmi yoki 300 ta bog'liqlikning biridanmi?
--trace-warnings har ogohlantirishga stek qo'shadi. Kanon chiqishi (t49-diag.txt):
(node:21748) Warning: sinov ogohlantirish
at [eval]:1:9
at runScriptInThisContext (node:internal/vm:219:10)Birinchi at qatori — ogohlantirish chaqirilgan joy. Eskirish uchun alohida bayroq — --trace-deprecation. Biz eskirgan new Buffer(4) ni ishga tushirdik:
(node:16184) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
(Use `node --trace-deprecation ...` to show where the warning was created)Tarjimasi: "Buffer() xavfsizlik va qulaylik sababli eskirgan; Buffer.alloc(), Buffer.allocUnsafe() yoki Buffer.from() ishlating". DEP0005 — eskirish kodi; Node hujjatida har kodning tarixi va o'rnini bosuvchi API bor. Buffer darsida nega new Buffer xavfli ekanini ko'rgansiz. --trace-deprecation bilan:
(node:7412) [DEP0005] DeprecationWarning: Buffer() is deprecated …
at showFlaggedDeprecation (node:buffer:224:11)
at new Buffer (node:buffer:307:3)
at file:///C:/Users/…/eskirgan.mjs:2:11Uchinchi qator — bizning faylimiz, 2-qator. Endi qidirish shart emas.
Yana ikki bayroq:
--throw-deprecation— eskirishni xatoga aylantiradi. Testlarda foydali: CI'da eskirgan API ishlatilsa, test yiqiladi.--no-deprecation— eskirish ogohlantirishlarini o'chiradi. Muammoni yashiradi — faqat ongli qaror bilan.
3.2 O'z eskirish ogohlantirishingiz
Kutubxona yozsangiz (valyuta ham kutubxona — index.ts eksport qiladi), bir kun funksiya nomini o'zgartirasiz. Eski nomni darhol o'chirish — foydalanuvchilar kodini buzish. To'g'ri yo'l: eskisini qoldirib, ogohlantirish berish. node:util dagi deprecate aynan shuni qiladi:
import { deprecate } from "node:util";
process.on("warning", (w) => {
console.log(`${w.name} [${w.code}]: ${w.message}`);
});
const eskiKonvert = deprecate(
(miqdor) => miqdor * 11903.15,
"eskiKonvert() o'rniga konvert() ishlating",
"VALYUTA001",
);
console.log(eskiKonvert(1));
console.log(eskiKonvert(2));Konsolda:
11903.15
23806.3
DeprecationWarning [VALYUTA001]: eskiKonvert() o'rniga konvert() ishlatingIkki narsaga qarang. Funksiya ikki marta chaqirildi, ogohlantirish — bir marta: bitta kod uchun deprecate bir marta xabar beradi, logni to'ldirmaydi. Va ogohlantirish natijalardan keyin chiqdi — Node uni asinxron yuboradi. Kodli ogohlantirish foydalanuvchiga uni aniq o'chirish imkonini beradi (--disable-warning=VALYUTA001).
Tekshirib ko'ring: CI'da testlar o'tadi, lekin logda 40 ta
DeprecationWarningbor. Ularni qanday "majburiy" qilasiz?
Javob
Test buyrug'iga --throw-deprecation qo'shing (masalan NODE_OPTIONS=--throw-deprecation). Endi har eskirish xato bo'ladi va test yiqiladi — jamoa ularni tuzatishga majbur. Bir vaqtda hammasini tuzatib bo'lmasa, avval --trace-deprecation bilan manbalarni toping va ro'yxat tuzing.
4. --trace-gc: GC'ning har qadami
Garbage collection darsida GC'ning ikki turini ko'rgansiz: yosh avlod uchun tez Scavenge va butun heap uchun Mark-Compact. --trace-gc har GC'ni bir qator qilib stdout'ga yozadi. 300 000 obyekt yaratadigan dasturda biz olgan birinchi qator:
[4944:0000022EFE5DF000] 27 ms: Scavenge 4.8 5.8-bob -> 4.3 6.8-bob MB, pooled: 0 MB, 0.98 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;Bo'laklab o'qiymiz:
| Bo'lak | Ma'nosi |
|---|---|
[4944:…] |
PID va izolyat manzili |
27 ms |
Jarayon boshidan o'tgan vaqt |
Scavenge |
GC turi (yosh avlod) |
4.8 5.8-bob -> 4.3 6.8-bob MB |
Ishlatilgan (ajratilgan) heap: oldin → keyin |
0.98 / 0.00 ms |
GC qancha vaqt oldi |
allocation failure |
Sabab: yangi obyektga joy qolmadi |
Shu dasturda 60 ms ichida beshta Scavenge bo'ldi, oxirgisi 20.0 → 18.0 MB, 12.98 ms. Kanon o'lchovi (t49-diag.txt) ham xuddi shunday: 5 qator, birinchisi 4.8 dan 4.4 MB ga.
Nima uchun kerak? Memory leak darsidagi "arra tishi"ni raqam bilan ko'rish uchun: har Mark-Compact'dan keyingi "keyin" qiymati o'sib borsa — sizish. Va GC vaqti uchun: Mark-Compact yuzlab millisekund olsa, shu vaqtda server javob bermaydi. average mu (mutator utilization) — vaqtning qancha qismi sizning kodingizga qoldi; 1.000 — GC deyarli xalaqit bermadi.
Maslahat:
--trace-gcchiqishi juda ko'p. Uni faylga yo'naltiring (node --trace-gc app.mjs > gc.log) va keyin faqatMark-Compactqatorlarini qidiring.
5. diagnostics_channel: kutubxona ichiga oyna
5.1 Muammo
Siz HTTP so'rovlarni kuzatmoqchisiz: qaysi manzilga, qachon. fetch Node ichida, uning kodini o'zgartira olmaysiz. Har fetch chaqiruviga console.log qo'yish — kodni iflos qiladi va bog'liqliklardagi fetch larni ko'rmaysiz.
diagnostics_channel (diagnostika kanali) — nomli kanal: kutubxona unga xabar yuboradi (publish), kim xohlasa obuna bo'ladi (subscribe). Obunachi bo'lmasa, yuborish deyarli bepul. O'xshatish: radio. Radiostansiya efirga uzatadi; radiosi yoqilgan odam eshitadi, yoqilmaganlar uchun hech narsa o'zgarmaydi.
5.2 O'z kanalingiz
import diagnostics_channel from "node:diagnostics_channel";
// kutubxona tomoni: kanal yaratadi va xabar yuboradi
const kanal = diagnostics_channel.channel("valyuta:kurs");
function kursniOl(kod) {
if (kanal.hasSubscribers) {
kanal.publish({ kod, manba: "kesh" });
}
return 11903.15;
}
kursniOl("USD"); // obunachi yo'q — hech narsa yuborilmaydi
// ilova tomoni: kerak bo'lganda obuna bo'ladi
function kuzat(xabar, nom) {
console.log(`${nom}:`, xabar);
}
diagnostics_channel.subscribe("valyuta:kurs", kuzat);
kursniOl("EUR");
diagnostics_channel.unsubscribe("valyuta:kurs", kuzat);
kursniOl("RUB");
console.log("tugadi");Konsolda:
valyuta:kurs: { kod: 'EUR', manba: 'kesh' }
tugadiFaqat EUR ko'rindi: USD paytida obunachi hali yo'q edi, RUB paytida — endi yo'q. hasSubscribers tekshiruvi xabar obyektini yaratishga ham pul sarflamaslik uchun.
Kanal nomi — kutubxona:hodisa ko'rinishida (kelishuv). Obunachi funksiya ikki argument oladi: xabar va kanal nomi. Bu EventEmitter ga o'xshaydi, lekin farqi bor: kanal global nom bo'yicha topiladi. Kutubxona va ilova bir-birini import qilishi shart emas.
5.3 Node'ning o'z kanallari
Node'ning ichki modullari ham kanallarga yozadi. fetch ni amalga oshiradigan undici — undici:request:create va boshqalar; http, net, child_process, worker_threads — o'z kanallari bilan (Node hujjatida ro'yxat bor). Biz fetch ni kuzatdik:
import diagnostics_channel from "node:diagnostics_channel";
const KANAL = "undici:request:create";
diagnostics_channel.subscribe(KANAL, ({ request }) => {
const { method, origin, path } = request;
console.log("so'rov:", method, origin + path);
});
try {
await fetch("http://127.0.0.1:59999/kurs/USD");
} catch (xato) {
console.log("xato:", xato.cause.code);
}Biz ishga tushirdik (59999 portida hech narsa yo'q edi):
so'rov: GET http://127.0.0.1:59999/kurs/USD
xato: ECONNREFUSEDSo'rov yaratilgani ulanishdan oldin ko'rindi. Biz fetch kodiga tegmadik. nocheck — natija tarmoqqa bog'liq: kompyuteringizda shu portda biror dastur bo'lsa, javob boshqacha bo'ladi. Built-in fetch darsidagi "bad port" tuzog'ini eslang: :9 port fetch uchun bloklangan.
Aynan shu mexanizm ustida APM vositalari (OpenTelemetry, Sentry, Datadog) ishlaydi: ular kodingizni o'zgartirmasdan har so'rov va so'rovlar vaqtini yig'adi.
5.4 Boshlanish, tugash va xato: tracingChannel
Bitta amalning boshlanishi, tugashi va xatosini kuzatish uchun tracingChannel bor — u bir nechta kanalni (start, end, error …) bitta nom ostida boshqaradi:
import diagnostics_channel from "node:diagnostics_channel";
const iz = diagnostics_channel.tracingChannel("valyuta:sorov");
iz.subscribe({
start: (x) => console.log("start", x.kod),
end: (x) => console.log("end", x.kod, x.result),
error: (x) => console.log("error", x.kod, x.error.message),
});
function kurs(kod) {
if (kod === "XYZ") throw new Error("noma'lum");
return 1;
}
iz.traceSync(kurs, { kod: "USD" }, null, "USD");
try {
iz.traceSync(kurs, { kod: "XYZ" }, null, "XYZ");
} catch {
// xatoni chaqiruvchi o'zi hal qiladi
}Konsolda:
start USD
end USD 1
start XYZ
error XYZ noma'lum
end XYZ undefinedtraceSync(funksiya, kontekst, this, ...argumentlar) — funksiyani chaqiradi va kontekst obyektiga result yoki error qo'shadi. Xato bo'lsa ham end keladi — "amal tugadi, muvaffaqiyatsiz". Asinxron funksiya uchun tracePromise bor.
Tekshirib ko'ring:
diagnostics_channelva oddiyconsole.logning asosiy farqi nima?
Javob
console.log har doim yozadi va kodni o'zgartirishni talab qiladi. Kanal esa faqat obunachi bo'lsa ishlaydi (aks holda deyarli bepul) va kuzatuvchi kodni kutubxonaga emas, o'z ilovasiga yozadi. Kutubxona muallifi bir marta kanal qo'yadi — har foydalanuvchi o'zi xohlagan narsani yig'adi.
6. perf_hooks: vaqtni o'lchash
6.1 mark va measure
Performansni o'lchash darsida performance.now() va benchmark qoidalarini ko'rgansiz. User Timing API (performance.mark, performance.measure) brauzerda ham, Node'da ham bir xil:
performance.mark("boshi");
const kurslar = Array.from({ length: 50_000 }, (_, i) => i % 97);
kurslar.sort((a, b) => a - b);
performance.mark("oxiri");
const o = performance.measure("saralash", "boshi", "oxiri");
console.log(o.name, o.entryType, o.duration >= 0);
console.log(performance.getEntriesByType("mark").map((m) => m.name));Konsolda:
saralash measure true
[ 'boshi', 'oxiri' ]Bu blok saytda ham ishlaydi — «Ishga tushir» bilan brauzerda sinang. Davomiylikning o'zini chiqarmadik: u har safar boshqacha. mark — vaqt belgisi, measure — ikki belgi orasidagi masofa. Afzalligi performance.now() ayirmasidan: nomlangan yozuvlar yig'iladi va ularni bitta joydan o'qish mumkin.
6.2 PerformanceObserver va timerify
Node'da node:perf_hooks qo'shimcha beradi. PerformanceObserver — yangi yozuv paydo bo'lganda chaqiriladi. performance.timerify(f) — funksiyani o'raydi: har chaqiruvi avtomatik function turidagi yozuv bo'ladi.
import { performance, PerformanceObserver } from "node:perf_hooks";
function kurslarniSarala(n) {
const kurslar = Array.from({ length: n }, (_, i) => (i * 7919) % n);
return kurslar.sort((a, b) => a - b);
}
const kuzatuvchi = new PerformanceObserver((royxat) => {
for (const y of royxat.getEntries()) {
const ms = y.duration.toFixed(1);
console.log(`${y.entryType} ${y.name}: ${ms} ms`);
}
});
kuzatuvchi.observe({ entryTypes: ["measure", "function"] });
performance.mark("boshi");
kurslarniSarala(200_000);
performance.mark("oxiri");
performance.measure("saralash", "boshi", "oxiri");
const olchanadigan = performance.timerify(kurslarniSarala);
olchanadigan(100_000);
olchanadigan(400_000);Biz ikki marta ishga tushirdik (Node 24.21.0, i5-12500H):
measure saralash: 60.3 ms
function kurslarniSarala: 30.6 ms
function kurslarniSarala: 143.1 msIkkinchi safar: 58.6, 29.4, 127.9 ms. Raqamlar o'zgaradi — shuning uchun nocheck. Lekin nisbat barqaror: 4 baravar ko'p ma'lumot — ~4.5 baravar ko'p vaqt (saralash n·log n).
perf_hooks da yana monitorEventLoopDelay bor — event loop kechikishini o'lchaydi. Uni Event loop'ni bloklash darsida ishlatgansiz.
7. Qaysi vosita qachon
flowchart TD
A["Muammo bor"] --> B{"Jarayon qulaydimi?"}
B -- "ha" --> C["--report-on-fatalerror va --report-uncaught-exception"]
B -- "yo'q" --> D{"Nima noto'g'ri?"}
D -- "xotira o'sadi" --> E["--trace-gc, heap snapshot"]
D -- "sekin" --> F["perf_hooks, --cpu-prof"]
D -- "noma'lum ogohlantirish" --> G["--trace-warnings"]
D -- "kutubxona ichi" --> H["diagnostics_channel"]Nimaga qarang: birinchi savol — "qulaydimi". Qulasa, qolgan vositalar kech qoladi — hisobot bayroqlari oldindan yoqilgan bo'lishi kerak. Qolgan hollarda belgi bo'yicha tanlaysiz. CPU profiling va heap snapshot — oldingi ikki darsda.
8. CLI qadami: holat yo'q — tajriba
valyuta da yangi kod yo'q. U allaqachon eng kerakli diagnostikaga ega: util moduli darsida qo'shilgan NODE_DEBUG=valyuta. Biz yakuniy holatda ishga tushirdik (oflayn rejim):
VALYUTA 7304: so'rov { kesh: '…/kesh', api: undefined, sana: undefined, olish: { kutishMs: undefined, signal: AbortSignal { aborted: false }, urinishdan: [Function: urinishdan] }, offline: true, yangila: false }
VALYUTA 7304: manba fixture, 74 kurs
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
2026-10-23 holatiga (fixture)
USD 1 11 903.15 -62.36 AQSH dollari7304 — PID. Debug qatorlari stderr'ga ketadi, natija stdout'da toza qoladi.
Nega process.report va kanallar kirmadi? CLI ~100 ms yashaydi va xato bo'lsa o'zi aniq xabar va exit kod beradi (process obyekti darsidagi 0/1/2/130). Qulash hisoboti uzoq yashaydigan server uchun. Kanon tajribasi (t49-diag.txt) bu vositalarni alohida sinadi: hisobot bo'limlari, --trace-gc 5 qator, --trace-warnings stek bilan. Commit yo'q.
9. Ko'p uchraydigan xatolar
9.1 --report-dir papkasi yo'q
Failed to open Node.js report file: report.… directory: hisobot (errno: 2)Node papka yaratmaydi. Ishga tushirish skriptida oldindan yarating (mkdir -p) va yozish huquqini tekshiring. Eng yomoni — bu xabar faqat qulash paytida chiqadi, ya'ni kech.
9.2 Hisobotni sirlar bilan ulashish
environmentVariables bo'limi — sirlar ro'yxati. Prodakshnda --report-exclude-env, ulashishdan oldin qidiruv.
9.3 Ogohlantirishni o'chirib qo'yish
--no-warnings yoki --no-deprecation "bezovta qiladi" deb qo'shiladi va keyin muhim xabar ham ko'rinmaydi. Aniq bittasini o'chirish kerak bo'lsa — --disable-warning=DEP0005 (kod bilan).
9.4 --report-on-signal Windows'da
Node yordam matni: Windows'da qo'llab-quvvatlanmaydi. Windows serverda hisobotni koddan (writeReport()) yoki xato bayroqlari bilan oling.
9.5 Bir martalik o'lchovga ishonish
timerify yoki measure bir marta 30 ms ko'rsatdi — bu raqam emas, taxmin. Biz ikki marta o'lchaganda 30.6 va 29.4 ms chiqdi. Qaror uchun bir necha o'lchov va mediana (Performansni o'lchash).
10. Mashqlar
Mashqlar kurs/mashqlar/24/49-diagnostika/ da.
1-mashq (oson): bo'sh joylarni to'ldiring
- Hisobotni koddan olish:
process.report.() - Heap tugaganda hisobot:
--report-on- - Hisobotdan muhit o'zgaruvchilarini olib tashlash:
--report-exclude- - Eskirish ogohlantirishi qayerdan kelganini ko'rish:
--trace- - Funksiya vaqtini avtomatik o'lchash:
performance.(f)
Yechim
- getReport — JSON obyekt;
writeReport()— faylga. - fatalerror —
--report-dirpapkasi oldindan bo'lishi shart. - env —
environmentVariablesbo'limi yo'qoladi. - deprecation — stek bilan; xatoga aylantirish —
--throw-deprecation. - timerify —
functionturidagi yozuvlarPerformanceObserverga keladi.
2-mashq (o'rta): hisobot xulosasi
hisobotXulosasi(r) funksiyasini yozing. U hisobot obyektidan qisqa xulosa qaytarsin: hodisa (header.event), sabab (header.trigger), heap ishlatilgani MB'da (javascriptHeap.usedMemory, bir xona aniqlikda) va muhit o'zgaruvchilaridan faqat nomlari sirga o'xshaganlari (KEY, SECRET, TOKEN, PASSWORD qatnashgan). Qiymatlarni hech qachon chiqarmang. Quyidagi namuna bilan sinang. Yordam: Object.keys va /KEY|SECRET|TOKEN|PASSWORD/i.test(nom) (RegExp asoslari).
const namuna = {
header: { event: "Exception", trigger: "Exception" },
javascriptHeap: { usedMemory: 4923984 },
environmentVariables: {
PATH: "C:/Windows",
JWT_SECRET: "juda-maxfiy",
VALYUTA_OFFLINE: "1",
NPM_TOKEN: "npm_abc",
},
};Yechim
function hisobotXulosasi(r) {
const env = r.environmentVariables ?? {};
const sirlar = Object.keys(env).filter((nom) =>
/KEY|SECRET|TOKEN|PASSWORD/i.test(nom),
);
const mb = r.javascriptHeap.usedMemory / 2 ** 20;
return [
`hodisa: ${r.header.event} (${r.header.trigger})`,
`heap: ${mb.toFixed(1)} MB`,
sirlar.length
? `DIQQAT, sirga o'xshash: ${sirlar.join(", ")}`
: "sirga o'xshash o'zgaruvchi yo'q",
].join("\n");
}
const namuna = {
header: { event: "Exception", trigger: "Exception" },
javascriptHeap: { usedMemory: 4923984 },
environmentVariables: {
PATH: "C:/Windows",
JWT_SECRET: "juda-maxfiy",
VALYUTA_OFFLINE: "1",
NPM_TOKEN: "npm_abc",
},
};
console.log(hisobotXulosasi(namuna));
const envsiz = { ...namuna, environmentVariables: undefined };
console.log(hisobotXulosasi(envsiz));Konsolda:
hodisa: Exception (Exception)
heap: 4.7 MB
DIQQAT, sirga o'xshash: JWT_SECRET, NPM_TOKEN
hodisa: Exception (Exception)
heap: 4.7 MB
sirga o'xshash o'zgaruvchi yo'qIkkinchi chaqiruv --report-exclude-env bilan olingan hisobotga teng: bo'lim yo'q, ?? {} buni ko'taradi. Bu funksiya ulashishdan oldingi tekshiruvni avtomatlashtiradi — faqat nomlarni ko'rsatadi, qiymatlarni emas.
3-mashq (qiyin): kanalli kutubxona
kursniOl(kod) asinxron funksiyasini yozing: 10 ms kutadi (new Promise((r) => setTimeout(r, 10))), XYZ uchun Error("noma'lum valyuta") tashlaydi, aks holda { kod, kurs: 11903.15 } qaytaradi. Uni tracingChannel("valyuta:kurs") ning tracePromise metodi bilan o'rang. Ilova tomonida asyncEnd va error hodisalariga obuna bo'lib, ok USD / xato XYZ: noma'lum valyuta deb chiqaring. USD va XYZ ni ketma-ket chaqiring (ikkinchisini try/catch bilan). Yordam: tracePromise(fn, kontekst, this, ...arg) — traceSync ning va'dali sherigi; natija kontekst.result da.
Yechim
import diagnostics_channel from "node:diagnostics_channel";
const iz = diagnostics_channel.tracingChannel("valyuta:kurs");
async function kursniOl(kod) {
await new Promise((r) => setTimeout(r, 10));
if (kod === "XYZ") throw new Error("noma'lum valyuta");
return { kod, kurs: 11903.15 };
}
const kuzatilgan = (kod) =>
iz.tracePromise(kursniOl, { kod }, null, kod);
iz.subscribe({
asyncEnd: (x) => {
if (!x.error) console.log("ok", x.result.kod);
},
error: (x) => console.log(`xato ${x.kod}: ${x.error.message}`),
});
await kuzatilgan("USD");
try {
await kuzatilgan("XYZ");
} catch {
console.log("chaqiruvchi ham xatoni oldi");
}Konsolda:
ok USD
xato XYZ: noma'lum valyuta
chaqiruvchi ham xatoni oldiXato bo'lganda ham asyncEnd keladi — shuning uchun unda x.error ni tekshirdik. Kanal xatoni "yutib yubormaydi": chaqiruvchi uni baribir oladi. Kuzatuv faqat qaraydi, oqimni o'zgartirmaydi — diagnostika vositasidan aynan shu talab qilinadi.
4-mashq: CLI qadami — valyuta ning eskirish ogohlantirishi
Loyihangizda tajriba qiling (commit qilmang): src/index.ts ga eskiKonvert nomli eksport qo'shing — u konvert ni deprecate bilan o'rasin (kod VALYUTA001). Kichik skriptda import { eskiKonvert } from "./src/index.ts" qilib ikki marta chaqiring. Keyin uni --trace-deprecation va --throw-deprecation bilan ishga tushiring va chiqishlarni solishtiring.
Yechim
Kutiladigan manzara (darsdagi deprecate blokidagidek): oddiy ishga tushirishda ogohlantirish bir marta, (node:PID) [VALYUTA001] DeprecationWarning: … ko'rinishida; --trace-deprecation bilan uning ostida stek, bitta qatori sizning skriptingizga ishora qiladi; --throw-deprecation bilan DeprecationWarning xato sifatida tashlanadi va jarayon 1 bilan tugaydi. Biz sinaganda --throw-deprecation da ham ikkala natija avval chiqdi — ogohlantirish asinxron, xato undan keyin keladi. Tajribadan keyin o'zgarishni qaytaring: valyuta da eskirgan API yo'q.
11. Real ishda
- Prodakshn sozlamasi: ko'p jamoalar servisni
--report-on-fatalerror --report-uncaught-exception --report-exclude-env --report-dir=…bilan ishga tushiradi. Qulashdan keyin hisobot — birinchi qarash joyi. - OpenTelemetry: kuzatuv standarti. Uning Node instrumentatsiyalari
diagnostics_channelga obuna bo'lib, so'rovlar va baza chaqiruvlarini kodga tegmasdan yig'adi. Backend qismlarida loglar va kuzatuv mavzusida qaytamiz. - Kutubxona mualliflari: Fastify, undici,
pgkabi paketlar o'z kanallarini e'lon qiladi. O'z kutubxonangizda ham kanal qo'yish — foydalanuvchilarga katta yordam. - Intervyu: "Prodakshnda debugger'siz nosozlikni qanday tahlil qilasiz?" — hisobot, loglar, trace bayroqlari, profil va heap snapshot, va ularni qachon yoqish kerakligi.
Xulosa
process.report— jarayonning JSON hisoboti;--report-on-fatalerror,--report-uncaught-exceptionuni qulash paytida yozadi.--report-dirpapkasi oldindan bo'lishi kerak;--report-on-signalWindows'da yo'q; sirlar uchun--report-exclude-env.--trace-warningsva--trace-deprecationogohlantirish manbasini ko'rsatadi;util.deprecate— o'z eskirish ogohlantirishingiz (bir marta, kod bilan).--trace-gcqatori: GC turi, heap oldin → keyin, davomiylik va sabab.diagnostics_channel— obunachi bo'lmasa bepul kuzatuv kanali;tracingChannel— start/end/error.perf_hooks:mark/measure(brauzerda ham),PerformanceObserver,timerify.
Keyingi dars: Node'da CLI dastur anatomiyasi — shebang, bin, argumentlar, stdout va stderr, exit kodlar va quvurlar: valyuta misolida hamma qism bir joyda.
Manbalar
- Node.js hujjati — Diagnostic report: https://nodejs.org/api/report.html
- Node.js hujjati — Diagnostics Channel: https://nodejs.org/api/diagnostics_channel.html
- Node.js hujjati — Performance measurement APIs: https://nodejs.org/api/perf_hooks.html
- Node.js hujjati — Deprecated APIs (DEP0005): https://nodejs.org/api/deprecations.html
- Node.js hujjati — CLI:
--trace-gc,--trace-warnings,--report-*: https://nodejs.org/api/cli.html
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!