Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. O'rnatilgan Logger
- 2.1 Xizmat ichida
- 2.2 Darajalar
- 3. Logger'ni almashtirish
- 3.1 ConsoleLogger({ json: true })
- 3.2 O'z LoggerService ingiz
- 4. bufferLogs va useLogger
- 5. nestjs-pino: ikki rejim
- 5.1 To'liq rejim
- 5.2 Kanon tajribasi: qaysi so'rov loglandi?
- 5.3 Nega yo'qoldi?
- 5.4 useExisting: true
- 6. Express'da qanday edi, Nest'da qanday
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): daraja va joy
- 2-mashq (o'rta): daraja filtri
- 3-mashq (qiyin): bufferLogs modeli
- 9. Loyiha qadami: Nest tizim loglari — bizning pino orqali
- 9.1 Paket
- 9.2 app.module.ts
- 9.3 ilova.ts
- 9.4 main.ts
- 9.5 Natija: bitta format
- 9.6 Yiqilishda — matn
- 9.7 Tekshiruv
- 10. Real ishda
- Xulosa
- Manbalar
NestJS logger: o'rnatilgan Logger, ConsoleLogger JSON va nestjs-pino
Qisqacha: Nest'ning o'z logger'i bor:
new Logger("Kontekst").log(...)—[Nest] … LOG [Kontekst] xabarko'rinishida matn chiqaradi. Ishga tushish, marshrutlar va ushlanmagan xatolar haqidagi tizim xabarlarini ham u yozadi. Prodakshnda bitta format kerak — JSON. Buning uchunapp.useLogger(...)bilan Nest'ga boshqa logger beriladi:ConsoleLogger({ json: true })yokinestjs-pino.bufferLogs: trueishga tushish xabarlarini yangi logger ulangunicha ushlab turadi. Tuzoq:nestjs-pinoning to'liq rejimi ba'zi so'rovlarni (400, statik fayl) umuman loglamaydi.
Bu darsda
- O'rnatilgan
Loggerva oltita log darajasini haqiqiy chiqish bilan ishlatasiz. ConsoleLogger({ json: true })va o'zLoggerServiceingizni yozasiz,errorimzosidagi tuzoqni bilasiz.bufferLogsvauseLoggernima uchun kerakligini tushuntirasiz.nestjs-pinoning ikki rejimini o'lchov bilan solishtirasiz va kanon negauseExistingni tanlaganini bilasiz.vazifalar-apida Nest tizim loglari bizning pino JSON logimizga o'tadi.
Oldin bilishingiz kerak: Logging asoslari, Pino chuqur, Correlation ID va so'rov kuzatuvi, Middleware Nest'da, Config validatsiyasi va namespace'lar.
O'tgan darsda config to'liq DI ichiga o'tdi va main.ts sakkiz parametrdan qutuldi. Lekin bitta parametr qoldi — nestLogi: ["error", "warn"]. Bu darsda u ham ketadi.
1. Nega bu kerak?
25-qismda vazifalar-api ga strukturali log qo'shgandik: Pino, har qator — JSON, har so'rovda sorovId (Pino chuqur). Nest'ga ko'chgach, stdout'ga ikkinchi "muallif" qo'shildi — Nest'ning o'zi. O'tgan darsdagi PORT=abc chiqishini eslang:
[Nest] … ERROR [ExceptionHandler] ConfigXatosi: Sozlama noto'g'ri:Shu jarayonning boshqa qatorlari esa JSON:
{"daraja":"info","ilova":"vazifalar-api","msg":"vazifalar-api: …"}Bitta ilova, ikki format. Log yig'uvchi tizim (34-qismda ko'radigan Loki kabi) JSON qatorni maydonlarga ajratadi, matn qatorni esa ajrata olmaydi. Natija: eng muhim xabar — ilova nega yiqilgani — qidiruvda topilmaydi.
O'xshatish: kassa daftari. Kassirlar bir xil jadvalga yozadi: sana, summa, kim. Bir kassir esa erkin matn bilan yozadi: "kechqurun bir oz pul oldim". Oy oxirida hisob yig'ilmaydi. Log — ilovaning kassa daftari: hamma bir formatda yozishi kerak.
2. O'rnatilgan Logger
2.1 Xizmat ichida
Nest'da logger olish uchun DI ham shart emas — Logger klassini o'zingiz yaratasiz:
@Injectable()
class BuyurtmaXizmati {
private readonly log = new Logger(BuyurtmaXizmati.name);
yarat(): void {
this.log.log("buyurtma yaratildi");
this.log.warn("ombor kam qoldi");
this.log.error("to'lov rad etildi");
this.log.debug("narx hisoblandi");
this.log.verbose("batafsil iz");
}
}BuyurtmaXizmati.name — klass nomi satr sifatida ("BuyurtmaXizmati"). U kontekst bo'ladi: har qatorda kvadrat qavsda turadi, log qayerdan kelganini ko'rsatadi. Nom o'zgarsa, kontekst ham o'zi yangilanadi.
Biz demo loyihada sinadik (biz ishga tushirdik: NestJS 12.2.0; jarayon raqami va vaqt … bilan almashtirildi):
[Nest] … LOG [NestFactory] Starting Nest application...
[Nest] … LOG [InstanceLoader] M dependencies initialized
[Nest] … LOG [BuyurtmaXizmati] buyurtma yaratildi
[Nest] … WARN [BuyurtmaXizmati] ombor kam qoldi
[Nest] … ERROR [BuyurtmaXizmati] to'lov rad etildi
[Nest] … DEBUG [BuyurtmaXizmati] narx hisoblandi
[Nest] … VERBOSE [BuyurtmaXizmati] batafsil izBirinchi ikki qator — bizniki emas. Bular Nest'ning tizim loglari: ilova ko'tarilmoqda, modul tayyor. Ular ham xuddi shu logger orqali chiqadi. Real ilovada ular ko'p: har modul, har marshrut (Mapped {/vazifalar, GET}), ushlanmagan xato (ExceptionHandler).
2.2 Darajalar
Nest'da oltita daraja bor: fatal, error, warn, log, debug, verbose. Ularni NestFactory.create ning logger sozlamasi bilan cheklash mumkin:
NestFactory.createApplicationContext(M, {
logger: ["error", "warn"],
});[Nest] … WARN [BuyurtmaXizmati] ombor kam qoldi
[Nest] … ERROR [BuyurtmaXizmati] to'lov rad etildiIshga tushish xabarlari ham yo'qoldi — ular log darajasida. logger: false — umuman jim (testlarda qulay). Pino'dagi darajalar bilan solishtirish:
| Nest | Pino | Ma'nosi |
|---|---|---|
fatal |
fatal |
jarayon to'xtaydi |
error |
error |
amal bajarilmadi |
warn |
warn |
g'alati, lekin ishlayapti |
log |
info |
oddiy voqea |
debug |
debug |
dasturchi uchun |
verbose |
trace |
eng batafsil |
Farq — nomda: Nest'ning log i pino'da info, verbose i — trace. nestjs-pino ularni shunday moslaydi. log → info ni pastdagi loyiha logida o'z ko'zingiz bilan ko'rasiz; verbose → trace — kutubxona hujjati bo'yicha.
Tekshirib ko'ring: Prodakshnda
logger: ["error", "warn"]qo'yildi. Ilova ishga tushdimi yoki yo'qligini logdan qanday bilasiz?
Javob
Nest'ning tizim loglaridan — bila olmaysiz: Nest application successfully started — log darajasida, u o'chirilgan. Shuning uchun kanonda main.ts o'zi info darajasida vazifalar-api: http://… qatorini yozadi. Umumiy qoida: "ishga tushdim" xabari doim ko'rinadigan darajada bo'lsin.
3. Logger'ni almashtirish
3.1 ConsoleLogger({ json: true })
Nest 11 dan beri o'rnatilgan logger JSON yoza oladi — kutubxonasiz. Logger nusxasi NestFactory ga beriladi:
NestFactory.createApplicationContext(M, {
logger: new ConsoleLogger({ json: true }),
});{"level":"log","pid":…,"timestamp":…,"message":"Starting Nest application...","context":"NestFactory"}
{"level":"log","pid":…,"timestamp":…,"message":"M dependencies initialized","context":"InstanceLoader"}
{"level":"log","pid":…,"timestamp":…,"message":"buyurtma yaratildi","context":"BuyurtmaXizmati"}
{"level":"warn","pid":…,"timestamp":…,"message":"ombor kam qoldi","context":"BuyurtmaXizmati"}
{"level":"error","pid":…,"timestamp":…,"message":"to'lov rad etildi","context":"BuyurtmaXizmati"}
{"level":"debug","pid":…,"timestamp":…,"message":"narx hisoblandi","context":"BuyurtmaXizmati"}
{"level":"verbose","pid":…,"timestamp":…,"message":"batafsil iz","context":"BuyurtmaXizmati"}(pid va timestamp qiymatlarini … bilan almashtirdik; timestamp — epoch millisekund.)
Endi JSON. Lekin bizning pino logimizdan farqli JSON: level — "log" (pino'da "info"), vaqt — timestamp raqami (bizda time ISO satri), xabar — message (bizda msg). Bitta stdout'da ikki xil JSON — yarim yechim. Bundan tashqari bu logger so'rovlarni umuman loglamaydi — faqat siz chaqirgan log(...) va Nest tizim xabarlari.
3.2 O'z LoggerService ingiz
logger sozlamasiga LoggerService interfeysiga mos har qanday obyekt berish mumkin: log, error, warn majburiy, debug, verbose, fatal ixtiyoriy.
class OzLogger implements LoggerService {
log(m: unknown, k?: string) {
console.log(`[o'z] INFO ${String(k)}: ${String(m)}`);
}
error(m: unknown, k?: string) {
console.log(`[o'z] XATO ${String(k)}: ${String(m)}`);
}
warn(m: unknown, k?: string) {
console.log(`[o'z] OGOH ${String(k)}: ${String(m)}`);
}
}[o'z] INFO NestFactory: Starting Nest application...
[o'z] INFO InstanceLoader: M dependencies initialized
[o'z] INFO BuyurtmaXizmati: buyurtma yaratildi
[o'z] OGOH BuyurtmaXizmati: ombor kam qoldi
[o'z] XATO undefined: to'lov rad etildiIkki narsaga qarang. Birinchisi: debug va verbose qatorlari yo'q — biz bu metodlarni yozmadik, Nest ularni jim o'tkazib yubordi. Ikkinchisi — tuzoq: XATO undefined. log va warn da ikkinchi argument kontekst edi, error da esa emas. error ning imzosi: error(xabar, stack?, kontekst?) — Nest ikkinchi o'ringa stack qo'yadi (bu yerda bo'sh), kontekst — oxirgi argument. Shuning uchun real LoggerService larda error(message: unknown, ...optionalParams: unknown[]) yoziladi va kontekst optionalParams.at(-1) dan olinadi.
4. bufferLogs va useLogger
Logger'ni NestFactory.create ga nusxa sifatida bersa bo'ladi. Lekin pino logger'imiz DI ichida yaratiladi (LOG provider'i config'ga tayanadi). DI esa create paytida yig'iladi. Tuxum va tovuq: logger'ni olish uchun ilova kerak, ilova ko'tarilayotganda yozilgan xabarlar uchun logger kerak.
Nest'ning yechimi — ikki qadam:
const app = await NestFactory.create(AppModule, {
bufferLogs: true, // tizim xabarlarini ushlab tur
});
app.useLogger(app.get(Logger)); // endi shu logger orqali chiqarbufferLogs: true — Nest ishga tushish xabarlarini xotirada yig'adi. useLogger chaqirilganda ular yangi logger orqali chiqadi. Natija: ishga tushish xabarlari ham JSON, ham bizning formatda.
Bir istisno bor — kanon uni o'lchab topgan. Agar ilova useLogger ga yetib kelmasa (fabrika yiqildi), yig'ilgan xabarlar Nest'ning sukut matnli ConsoleLogger iga chiqadi. Biz ham buni ko'rdik: «Loyiha qadami» bo'limida PORT=abc bilan sinaymiz.
5. nestjs-pino: ikki rejim
5.1 To'liq rejim
nestjs-pino — Nest uchun pino ko'prigi. Uning hujjatidagi asosiy ulash:
@Module({
imports: [
LoggerModule.forRoot({ pinoHttp: { level: "info" } }),
],
})
export class AppModule {}
// main.ts
const app = await NestFactory.create(AppModule, { bufferLogs: true });
app.useLogger(app.get(Logger)); // Logger — nestjs-pino'danBu rejimda paket uch ish qiladi: Nest tizim loglarini pino'ga yo'naltiradi; xizmatlarga PinoLogger beradi; va pino-http ni o'zi ulaydi — so'rov loglari uchun. Uchinchisi — Nest modul middleware'i sifatida (Middleware Nest'da).
5.2 Kanon tajribasi: qaysi so'rov loglandi?
Kanon tajribasi bir xil ilovaga to'rt so'rov yubordi: GET /v (oddiy), POST /v yaroqsiz JSON bilan (400), GET /index.html (statik fayl) va GET /yoq (404). Uch variant solishtirildi. Natija (kanon o'lchovi, IlmHamroh, 2026-10, NestJS 12.2.0; kanon chiqishi o'zgarishsiz):
A) nestjs-pino TO'LIQ (pino-http — Nest modul middleware'i)
bootstrap qatorlari: 7 (birinchisi: {"level":30,"context":"NestFactory","msg":"Starting Nest application..."})
so'rovlardan keyingi qatorlar:
GET /v → undefined "xizmat logi (PinoLogger)"
GET /v → 200 "request completed"
GET /yoq → 404 "request completed"
B) KANON: pino-http app.use (Nest'dan oldin) + nestjs-pino useExisting
bootstrap qatorlari: 7 (birinchisi: {"level":30,"context":"NestFactory","msg":"Starting Nest application..."})
so'rovlardan keyingi qatorlar:
GET /v → undefined "xizmat logi (PinoLogger)"
GET /v → 200 "request completed"
POST /v → 400 "request completed"
GET /index.html → 200 "request completed"
GET /yoq → 404 "request completed"
C) ConsoleLogger({ json: true }) — o'rnatilgan
bootstrap qatorlari: 6 (birinchisi: {"level":"log","pid":16072,"timestamp":1793115874514,"message":"Starting Nest application...","context":"NestF)
so'rovlardan keyingi qatorlar:
(ilova) controller logiNatijani jadvalga yig'amiz:
| So'rov | A (to'liq) | B (kanon) | C (JSON Console) |
|---|---|---|---|
GET /v 200 |
bor | bor | yo'q |
POST /v 400 |
yo'q | bor | yo'q |
GET /index.html |
yo'q | bor | yo'q |
GET /yoq 404 |
bor | bor | yo'q |
A variantda ikki so'rov izsiz o'tdi. Yaroqsiz JSON — hujum yoki buzuq mijozning eng tipik belgisi. Aynan u logda yo'q.
5.3 Nega yo'qoldi?
Sabab — middleware tartibi. 25-qismdagi zanjirni eslang: so'rov middleware'lardan ketma-ket o'tadi, kimdir javob bersa, keyingilari ishlamaydi (Middleware va request lifecycle).
flowchart TB
S["so'rov"] --> P["pino-http (app.use) — B"]
P --> ST["statik fayllar"]
ST -->|"index.html topildi"| J1["javob 200"]
ST --> JS["express.json"]
JS -->|"yaroqsiz JSON"| J2["javob 400"]
JS --> NM["Nest modul middleware — A"]
NM --> C["controller"]A variantda pino-http — Nest modul middleware'i. U faqat so'rov Nest marshrutlariga yetib kelganda ishlaydi. Statik fayl undan oldin javob topdi, yaroqsiz JSON esa express.json da 400 bilan to'xtadi. Ikkalasi pino-http gacha yetmadi. B variantda pino-http — eng boshida, app.use bilan. U har so'rovni ko'radi va javob yopilganda yozadi — kim javob berganidan qat'i nazar.
5.4 useExisting: true
Kanondagi ulash:
LoggerModule.forRootAsync({
inject: [LOG],
useFactory: (log: Log) => ({
pinoHttp: { logger: log },
useExisting: true,
}),
}),forRootAsync+inject: [LOG]— o'tgan darsdan oldingi naqsh:nestjs-pinobizningLOGprovider'imizdagi pino nusxasini oladi. Yangi logger yaratilmaydi — format,redact,ilovamaydoni hammasi o'sha.useExisting: true— "o'zpino-httpingni ulama, so'rov logi allaqachon bor".nestjs-pinofaqat Nest tizim loglarini yo'naltiradi. So'rov logini 25-qismdagisorovLogi()yozadi —app.usebilan, eng boshida.
Natija: B qatori — hamma so'rov loglanadi va Nest tizim xabarlari ham bitta JSON formatda.
Diqqat: Kanon ham
nestjs-pinodan foydalanadi — faqat to'liq rejimidan emas. Paketni tashlash shart emas; uning middleware'ini o'zingiz to'g'ri joyga qo'yasiz.
6. Express'da qanday edi, Nest'da qanday
| 25–27 (Express) | Nest (kanon) | |
|---|---|---|
| So'rov logi | pino-http, app.use |
o'sha — app.use, Nest'dan oldin |
| Xizmat logi | joriyLog(log) |
o'sha (keyingi darsda — CLS orqali) |
| Tizim xabarlari | yo'q edi | nestjs-pino → bizning pino |
| Ishga tushish xatosi | console.error |
Nest matni + console.error |
Express'da tizim xabarlari umuman yo'q edi — Express jim ishga tushadi. Nest esa ko'p gapiradi: biz yurgizgan loyiha logida ishga tushishning o'zi 30 dan ortiq qator (har modul, har marshrut). Prodakshnda bu shovqin: LOG_LEVEL=warn qo'yilsa, ular yo'qoladi, lekin main.ts dagi "ishga tushdim" ham info da. Kanon info ni qoldiradi — marshrutlar ro'yxati deploy'dan keyin "qaysi versiya ishlayapti" savoliga javob beradi.
7. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| Ishga tushish loglari matnda, qolgani JSON | bufferLogs yo'q |
bufferLogs: true + useLogger |
| 400 va statik so'rovlar logda yo'q | nestjs-pino to'liq rejimi |
pino-http — app.use, useExisting: true |
XATO undefined: … |
error ning 2-argumenti — stack |
...optionalParams, kontekst — oxirgisi |
debug loglari chiqmaydi |
LoggerService da metod yo'q yoki daraja yuqori |
metodni yozing, darajani tekshiring |
| Ikki xil JSON bir stdout'da | ConsoleLogger({ json: true }) + pino |
bitta logger: nestjs-pino |
| Yiqilishda xato matnli | logger ulanmasdan fabrika yiqildi | kutilgan; main.ts o'z qisqa xabarini yozadi |
8. Mashqlar
Mashqlar kurs/mashqlar/30/29-nestjs-logger/ da.
1-mashq (oson): daraja va joy
To'ldiring:
- Nest'ning
logdarajasi pino'da — - Pino'da
tracega mos Nest darajasi — logger: ["error", "warn"]daNest application successfully startedchiqadimi? —- Yaroqsiz JSON (400) logda bo'lishi uchun
pino-httpqayerda ulanadi?app.bilan, Nest marshrutlaridan oldin.
Yechim
- info va verbose — jadvaldagi moslik.
- yo'q — bu xabar
logdarajasida. - use —
app.use(sorovLogi(l)); Nest modul middleware'i 400 dan keyin ishlamaydi.
2-mashq (o'rta): daraja filtri
Brauzerda ishlaydigan loggerYasa(daraja) yozing. U Nest uslubidagi obyekt qaytarsin: log, warn, error, debug, verbose metodlari. Har metod xabarni pino darajasiga moslab (log → info, verbose → trace), faqat chegaradan yuqori yoki teng bo'lsa JSON qilib chiqarsin: {"daraja":"info","context":"…","msg":"…"}. Pino tartibi: trace 10, debug 20, info 30, warn 40, error 50. Ishora: obyekt bo'ylab yurish va JSON.stringify.
Yechim
const MOSLIK = {
verbose: "trace", debug: "debug", log: "info",
warn: "warn", error: "error",
};
const RAQAM = { trace: 10, debug: 20, info: 30, warn: 40, error: 50 };
function loggerYasa(daraja) {
const chegara = RAQAM[daraja];
const logger = {};
for (const [nest, pinoD] of Object.entries(MOSLIK)) {
logger[nest] = (msg, context) => {
if (RAQAM[pinoD] < chegara) return;
console.log(JSON.stringify({ daraja: pinoD, context, msg }));
};
}
return logger;
}
const l = loggerYasa("info");
l.log("buyurtma yaratildi", "BuyurtmaXizmati");
l.debug("narx hisoblandi", "BuyurtmaXizmati");
l.warn("ombor kam qoldi", "BuyurtmaXizmati");
const t = loggerYasa("trace");
t.verbose("batafsil iz", "BuyurtmaXizmati");Konsolda:
{"daraja":"info","context":"BuyurtmaXizmati","msg":"buyurtma yaratildi"}
{"daraja":"warn","context":"BuyurtmaXizmati","msg":"ombor kam qoldi"}
{"daraja":"trace","context":"BuyurtmaXizmati","msg":"batafsil iz"}debug qatori info chegarasida chiqmadi. Bu LOG_LEVEL ning ishi: kanonda u config'dan pino'ga beriladi, nestjs-pino esa Nest xabarlarini shu pino orqali o'tkazadi — filtr bitta joyda.
3-mashq (qiyin): bufferLogs modeli
ilovaYarat({ bufer, yiqil }) modelini yozing. Ishga tushish uch xabar yozadi ("Starting Nest application...", "AppModule dependencies initialized", "Nest application successfully started"). bufer: true bo'lsa, xabarlar massivda yig'iladi. yiqil: true bo'lsa, ikkinchi xabardan keyin Error("ConfigXatosi") tashlanadi. Logger ulanishi (useLogger) — muvaffaqiyatli yaratilgandan keyin. Qoida: ulanganda yig'ilganlar JSON logger'ga, yiqilganda — sukut matnli logger'ga chiqsin ([Nest] LOG xabar). bufer: false da har xabar darhol matnli chiqadi.
Yechim
const matnli = (m) => console.log(`[Nest] LOG ${m}`);
const json = (m) =>
console.log(JSON.stringify({ daraja: "info", msg: m }));
function ilovaYarat({ bufer, yiqil }) {
const yigilgan = [];
const yoz = (m) => (bufer ? yigilgan.push(m) : matnli(m));
try {
yoz("Starting Nest application...");
yoz("AppModule dependencies initialized");
if (yiqil) throw new Error("ConfigXatosi");
yoz("Nest application successfully started");
} catch (e) {
yigilgan.forEach(matnli); // useLogger'ga yetmadik
console.log(`[Nest] ERROR ${e.message}`);
return null;
}
yigilgan.forEach(json); // useLogger: yig'ilganlar yangi logger'ga
return { useLogger: true };
}
console.log("— bufer, muvaffaqiyat");
ilovaYarat({ bufer: true, yiqil: false });
console.log("— bufer, yiqildi");
ilovaYarat({ bufer: true, yiqil: true });
console.log("— bufersiz");
ilovaYarat({ bufer: false, yiqil: false });Konsolda:
— bufer, muvaffaqiyat
{"daraja":"info","msg":"Starting Nest application..."}
{"daraja":"info","msg":"AppModule dependencies initialized"}
{"daraja":"info","msg":"Nest application successfully started"}
— bufer, yiqildi
[Nest] LOG Starting Nest application...
[Nest] LOG AppModule dependencies initialized
[Nest] ERROR ConfigXatosi
— bufersiz
[Nest] LOG Starting Nest application...
[Nest] LOG AppModule dependencies initialized
[Nest] LOG Nest application successfully startedIkkinchi holat — loyiha qadamidagi PORT=abc chiqishining modeli: yig'ilgan xabarlar matnda chiqdi, chunki JSON logger hali yaratilmagan edi. Uchinchisi — bufferLogs siz Nest: ishga tushish xabarlari doim sukut logger'da.
9. Loyiha qadami: Nest tizim loglari — bizning pino orqali
Config, log va so'rov konteksti qadamining uchinchi qismi. Commit — keyingi darsda.
9.1 Paket
npm install --save-exact nestjs-pino@5.3.1pino 10.4.0 va pino-http 11.0.0 — 25-qismdan beri bor.
9.2 app.module.ts
Importlarga ikki qator:
import { LoggerModule } from "nestjs-pino";
import { LOG } from "./tokenlar.ts";
import type { Log } from "./umumiy/log.ts";imports massivida BogliqliklarModule.forRoot(b) dan keyin — «useExisting: true» bo'limidagi LoggerModule.forRootAsync(...) bloki. LOG provider'i global BogliqliklarModule da — inject: [LOG] uni ko'radi.
9.3 ilova.ts
nestLogi parametri va LogLevel importi o'chadi. Import qo'shiladi: import { Logger } from "nestjs-pino";. Ilova yaratish:
// bufferLogs — Nest loglari pino Logger ulangunicha yig'iladi
const app = await NestFactory.create<NestExpressApplication>(
AppModule.forRoot({
ombor, config, log, xabarchi, tz, idempotentlikOmbori,
}),
{ bodyParser: false, bufferLogs: true, abortOnError: false },
);
app.useLogger(app.get(Logger));Logger — nestjs-pino niki, @nestjs/common dagi emas. Nomlar bir xil — import qatoriga qarang. app.get(Logger) — LoggerModule yaratgan, LoggerService interfeysiga mos obyekt.
9.4 main.ts
Oxirgi parametr ham ketadi:
ishlayotgan = await ishgaTushir({ bogliqliklar: {} });{} — "hech narsani ustidan yozma, hammasi config'dan".
9.5 Natija: bitta format
npm run build, keyin SAQLASH=xotira node dist/main.js va uch so'rov: oddiy POST, yaroqsiz JSON va /index.html. Biz yurgizdik (biz ishga tushirdik; time maydonini olib tashladik, 34 qatordan boshi va oxiri):
{"daraja":"info","ilova":"vazifalar-api","context":"NestFactory","msg":"Starting Nest application..."}
{"daraja":"info","ilova":"vazifalar-api","context":"InstanceLoader","msg":"ConfigHostModule dependencies initialized"}
{"daraja":"info","ilova":"vazifalar-api","context":"InstanceLoader","msg":"ConfigModule dependencies initialized"}
{"daraja":"info","ilova":"vazifalar-api","context":"RouterExplorer","msg":"Mapped {/vazifalar, GET} (version: 1,Neutral) route"}
{"daraja":"info","ilova":"vazifalar-api","context":"NestApplication","msg":"Nest application successfully started"}
{"daraja":"info","ilova":"vazifalar-api","manzil":"http://127.0.0.1:45829","muhit":"development","saqlash":"xotira","msg":"vazifalar-api: http://127.0.0.1:45829"}
{"daraja":"info","ilova":"vazifalar-api","sorovId":"aziz-0001","vazifaId":1,"msg":"vazifa yaratildi"}
{"daraja":"info","ilova":"vazifalar-api","sorovId":"aziz-0001","req":{"method":"POST","url":"/v1/vazifalar","ip":"127.0.0.1","userAgent":"node"},"res":{"status":201},"ms":27,"msg":"POST /v1/vazifalar 201"}
{"daraja":"warn","ilova":"vazifalar-api","sorovId":"aziz-0002","req":{"method":"POST","url":"/v1/vazifalar","ip":"127.0.0.1","userAgent":"node"},"res":{"status":400},"ms":3,"msg":"POST /v1/vazifalar 400"}
{"daraja":"info","ilova":"vazifalar-api","sorovId":"aziz-0003","req":{"method":"GET","url":"/index.html","ip":"127.0.0.1","userAgent":"node"},"res":{"status":200},"ms":3,"msg":"GET /index.html 200"}Hamma qator — bitta format: daraja, ilova, msg. Nest'ning xabarlarida qo'shimcha context (NestFactory, RouterExplorer). Nest LOG i — "daraja":"info": darajalar jadvalidagi moslik. Yaroqsiz JSON (aziz-0002) va statik fayl (aziz-0003) — logda. Ular kanon tajribasining B qatori.
O'tgan darsda, bu o'zgarishdan oldin, xuddi shu so'rovlarda logda faqat oxirgi to'rt qator bor edi — Nest'ning 30 dan ortiq ishga tushish xabari logger: ["error", "warn"] bilan o'chirilgan edi.
9.6 Yiqilishda — matn
PORT=abc node dist/main.js; echo "exit $?"[Nest] … LOG [NestFactory] Starting Nest application...
[Nest] … ERROR [ExceptionHandler] ConfigXatosi: Sozlama noto'g'ri:
✖ butun son bo'lishi kerak (bo'sh qiymat — xato)
→ at PORT
at configYukla (file:///C:/Users/…/dist/config.js:74:15)
at InstanceWrapper.metatype (file:///C:/Users/…/dist/bogliqliklar.module.js:24:59)
Sozlama noto'g'ri:
✖ butun son bo'lishi kerak (bo'sh qiymat — xato)
→ at PORT
exit 78(Jarayon raqami, vaqt, lokal yo'llar qisqartirildi; Nest injektorining sakkiz qatori olib tashlandi.)
Endi birinchi qatorda LOG [NestFactory] Starting… ham bor — bufferLogs uni yig'ib turgan edi. Lekin JSON emas, matn. Sabab: LoggerModule LOG ga, LOG esa CONFIG ga tayanadi — CONFIG fabrikasi yiqildi va pino logger umuman yaratilmadi. useLogger ga navbat kelmadi, yig'ilgan xabarlar sukut logger'ga chiqdi — 3-mashqdagi ikkinchi holat. Bu tuzatib bo'lmaydigan cheklov: logger'ning o'zi config'ga muhtoj. Kanon buni qabul qiladi — main.ts dagi qisqa console.error qatori va exit 78 baribir aniq.
9.7 Tekshiruv
npm run tip && npm run lint && npm test && npm run buildBiz holat nusxasida yurgizdik (Postgres'siz): tip 0, lint 0, build o'tdi. Vitest bir yugurishda 1 failed | 74 passed | 6 skipped berdi — yiqilgani jarayon.test.ts ("unhandledRejection … let it crash"). Yolg'iz yurgizilganda u 3 s da o'tdi, keyingi to'liq yugurishda ham 75 passed | 6 skipped. Bu test bola jarayon ishga tushiradi va 20 s kutadi. Parallel testlar bilan band mashinada bola jarayon kechikadi — kanon ham shuni ko'rgan. Tuzatish — keyingi darsdagi timeout'lar. Sizda ham bir marta yiqilsa — qayta yurgizing. Hali commit qilmang.
10. Real ishda
- Nest loyihalarida
nestjs-pino— eng ko'p ishlatiladigan logger paketi. UningPinoLoggerva@InjectPinoLoggerdekoratorini ko'p kodda uchratasiz. - Log yig'ish (Loki, ELK, CloudWatch) faqat JSON bilan to'g'ri ishlaydi — matnli
[Nest]qatorlari alohida qoida talab qiladi. Bitta format — operatsiya jamoasining birinchi talabi. - Middleware tartibi — "nega bu xato logda yo'q?" savolining eng ko'p uchraydigan javobi. Logger zanjirning eng boshida bo'lsin.
- Intervyu: "Nest'da logger'ni qanday almashtirasiz?", "
bufferLogsnima uchun?", "nestjs-pinoqaysi so'rovlarni loglamasligi mumkin?".
Xulosa
new Logger(Klass.name)— kontekstli log; darajalar:fatal,error,warn,log,debug,verbose.- Nest tizim xabarlari ham shu logger orqali;
logger: [...]— daraja ro'yxati,false— jim. ConsoleLogger({ json: true })— kutubxonasiz JSON, lekin pino formatidan farqli va so'rov logisiz.LoggerService.errorning ikkinchi argumenti — stack; kontekst — oxirgi.bufferLogs+useLogger— ishga tushish xabarlari ham yangi logger orqali; fabrika yiqilsa — sukut matn.nestjs-pinoto'liq rejimi 400 va statik so'rovlarni loglamaydi; kanon —pino-httpapp.usebilan +useExisting: true.
Keyingi dars: So'rov konteksti: nestjs-cls — 25-qismdagi o'z AsyncLocalStorage imizni nestjs-cls ga almashtiramiz va loyiha qadamini commit qilamiz.
Manbalar
- NestJS hujjati — Logger (darajalar, JSON rejimi,
bufferLogs,useLogger,LoggerService): https://docs.nestjs.com/techniques/logger nestjs-pinoREADME (forRootAsync,useExisting, darajalar mosligi): https://github.com/iamolegga/nestjs-pinopino-http: https://github.com/pinojs/pino-http- Kanon (IlmHamroh, 2026-10-27): config/log/kontekst qadami —
LoggerModule.forRootAsync+useExisting,bufferLogs; uch variantli so'rov logi tajribasi (NestJS 12.2.0,nestjs-pino5.3.1). O'rnatilganLogger,ConsoleLogger({ json: true }),LoggerServicetajribalari, loyihaning ishga tushish logi vaPORT=abcchiqishi — biz ishga tushirdik (2026-11-02, NestJS 12.2.0, Node 24.21.0).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!