Skip to main content
Практика завдань

Як реалізувати логування в Express.js (Morgan, Winston)?

Логування в Express.js

Правильне логування є важливим для налагодження, моніторингу та аудиту виробничих застосунків. Express використовує дві основні бібліотеки для логування: Morgan для логування HTTP запитів та Winston для логування на рівні застосунку.


Morgan — Логгер HTTP Запитів

Morgan логує кожен вхідний HTTP запит:

bash
npm install morgan
js
const morgan = require('morgan'); // Попередньо визначені формати app.use(morgan('dev')); // Кольоровий вивід для розробки app.use(morgan('combined')); // Apache-стиль для виробництва app.use(morgan('tiny')); // Мінімальний вивід

Приклади форматів:

// dev формат: GET /api/users 200 12.345 ms - 250 // combined формат: ::1 - - [01/Mar/2026:10:00:00 +0000] "GET /api/users HTTP/1.1" 200 250 // tiny формат: GET /api/users 200 250 - 12.345 ms

Користувацький формат:

js
morgan.token('body', (req) => JSON.stringify(req.body)); app.use(morgan(':method :url :status :response-time ms - :body'));

Логування у файл:

js
const fs = require('fs'); const path = require('path'); const accessLogStream = fs.createWriteStream( path.join(__dirname, 'access.log'), { flags: 'a' } ); app.use(morgan('combined', { stream: accessLogStream }));

Winston — Логгер Застосунку

Winston є універсальною бібліотекою для логування з кількома транспортами:

bash
npm install winston
js
const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ), defaultMeta: { service: 'my-api' }, transports: [ new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), new winston.transports.File({ filename: 'logs/combined.log' }) ] }); // Додати консоль у розробці if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ) })); }

Використання:

js
logger.info('Сервер запущено', { port: 3000 }); logger.warn('Виявлено повільний запит', { query: 'SELECT...', duration: 5000 }); logger.error('Не вдалося підключитися до бази даних', { error: err.message });

Комбінування Morgan + Winston

js
const morganStream = { write: (message) => logger.http(message.trim()) }; app.use(morgan('combined', { stream: morganStream }));

Рівні Логування

РівеньПріоритетВикористання
error0Помилки застосунку
warn1Депрекації, повільні запити
info2Ключові події (запуск, зупинка)
http3HTTP запити
debug4Детальне налагодження
verbose5Ще більше деталей
silly6Все

Найкращі Практики

ПрактикаОпис
Структуроване логуванняВикористовуйте формат JSON для машинного парсингу
ID запитуДодайте унікальний ID для відстеження запитів у логах
Не логувати секретиФільтруйте паролі, токени, кредитні картки
Ротація логівВикористовуйте winston-daily-rotate-file
Централізоване логуванняВідправляйте в ELK Stack, Datadog або CloudWatch
Різні рівні для середовищаdebug у розробці, info у виробництві
js
// Middleware для ID запиту const { v4: uuid } = require('uuid'); app.use((req, res, next) => { req.requestId = req.headers['x-request-id'] || uuid(); res.setHeader('x-request-id', req.requestId); next(); });

Порада для виробництва: Завжди використовуйте структуроване JSON логування. Прикріплюйте ID запитів для відстеження. Відправляйте логи до централізованого сервісу. Ніколи не логуйте чутливі дані, такі як паролі, токени або особисту інформацію.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань