로깅 (Logging)은 모든 애플리케이션에서 중요한 부분입니다. 로깅은 코드 디버깅, 모니터링 및 유지 관리에 도움이 됩니다. Winston 은 유연성과 풍부한 기능으로 인해 Node.js에서 가장 인기 있는 로깅 라이브러리 중 하나입니다. 이 글에서는 Winston을 Node.js 애플리케이션에 통합하고 그 기능을 최대한 활용하는 방법을 살펴봅니다.
개요
이 튜토리얼에서는 다음을 다룹니다:
Node.js 프로젝트에서 Winston 설정하기
다양한 로깅 수준 구성하기
사용자 정의 로그 형식 만들기
여러 전송(콘솔, 파일 등)에 로깅하기
사용자 지정 로그 수준 만들기
일일 로그 파일에 로깅하기
Express 애플리케이션에서 Winston 사용하기
전제 조건
JavaScript 및 Node.js에 대한 기본 지식
npm 및 Express에 익숙함(선택 사항이지만 마지막 단계에 권장됨).
설정
Node.js 프로젝트를 초기화합니다.
1 2 3 mkdir winston-logger-example cd winston-logger-examplenpm init -y
Winston를 설치합니다.
1 npm install express winston winston-daily-rotate-file
기본 설정
Winston을 설정하기 위한 logger.js
파일을 생성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const { createLogger, format, transports } = require ('winston' );const logger = createLogger({ level: 'info' , format: format.combine( format.colorize(), format.timestamp(), format.printf(({ timestamp, level, message } ) => `${timestamp} ${level} : ${message} ` ) ), transports: [new transports.Console(), new transports.File({ filename : 'app.log' })], }); module .exports = logger;
createLogger: 새 로거 인스턴스를 초기화합니다.
format.combine: 여러 형식을 결합합니다. 여기서는 colorize
, timestamp
, printf
를 사용하고 있습니다.
transports: 로그를 전송할 위치를 지정합니다. 이 예에서는 콘솔과 파일(app.log
)에 로깅합니다.
로깅 레벨 구성하기
Winston은 error
, warn
, info
, http
, verbose
, debug
, silly
등 여러 로깅 레벨을 지원합니다. 캡처할 로그의 최소 레벨을 구성할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const { createLogger, format, transports } = require ('winston' );const logger = createLogger({ levels: { error: 0 , warn: 1 , info: 2 , http: 3 , verbose: 4 , debug: 5 , silly: 6 , }, level: 'info' , format: format.combine( format.colorize(), format.timestamp(), format.printf(({ timestamp, level, message } ) => `${timestamp} ${level} : ${message} ` ) ), transports: [new transports.Console(), new transports.File({ filename : 'app.log' })], }); module .exports = logger;
levels: 사용자 정의 로깅 레벨을 정의합니다.
level: 캡처할 로그의 최소 레벨을 설정합니다(여기서는 info
로 설정되어 있음).
로그 레벨 이해하기
로그 레벨은 기록되는 메시지의 심각도를 결정합니다. Winston은 가장 심각한 것부터 가장 덜 심각한 것까지 우선순위가 지정된 npm 스타일 로깅 레벨을 사용합니다.
error: (0) 즉각적인 주의가 필요할 수 있는 오류를 로깅합니다.
warn: (1) 잠재적 문제를 나타내는 경고를 로깅합니다.
info: (2) 애플리케이션의 진행 상황을 강조하는 정보 메시지를 로깅합니다.
http: (3) HTTP 요청을 로깅합니다.
verbose: (4) 디버깅 중 유용한 상세 정보를 로깅합니다.
debug: (5) 디버깅 정보를 기록합니다.
silly: (6) 가장 자세한 정보, 종종 필요 이상으로 많은 정보를 로깅합니다.
최소 로그 레벨을 설정하여 덜 심각한 메시지를 필터링할 수 있습니다. 예를 들어 로그 레벨을 info
로 설정하면 info
, warn
및 error
메시지만 기록됩니다.
사용자 지정 로그 형식 만들기
필요에 따라 사용자 지정 로그 형식을 만들 수 있습니다. 예를 들어 메타데이터를 추가하거나 로그 메시지 구조를 변경할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const { createLogger, format, transports } = require ('winston' );const customFormat = format.combine( format.colorize(), format.timestamp(), format.printf(({ timestamp, level, message, ...meta } ) => { return `${timestamp} ${level} : ${message} ${Object .keys(meta).length ? JSON .stringify(meta, null , 2 ) : '' } ` ; }) ); const logger = createLogger({ level: 'info' , format: customFormat, transports: [new transports.Console(), new transports.File({ filename : 'app.log' })], }); module .exports = logger;
customFormat: timestamp, log level, message 및 optional metadata를 구조화된 로그 형식으로 결합합니다.
여러 전송에 로깅
Winston은 다양한 파일, 외부 로깅 서비스 또는 콘솔과 같은 여러 대상에 로깅할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const { createLogger, format, transports } = require ('winston' );const logger = createLogger({ level: 'info' , format: format.combine( format.timestamp(), format.printf(({ timestamp, level, message } ) => `${timestamp} ${level} : ${message} ` ) ), transports: [ new transports.Console(), new transports.File({ filename : 'app.log' }), new transports.File({ filename : 'error.log' , level : 'error' }), ], }); module .exports = logger;
transports.File({ filename: ‘error.log’, level: ‘error’ }): 오류 메시지를 별도의 파일에 기록합니다.
사용자 정의 로그 레벨 생성
Winston에서 사용자 지정 로그 레벨을 직접 정의할 수 있습니다. 이 기능은 기본 레벨에서 다루지 않는 특정 요구 사항이 있는 경우에 유용합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const { createLogger, format, transports, config } = require ('winston' );const customLevels = { levels: { critical: 0 , error: 1 , warn: 2 , info: 3 , debug: 4 , }, colors: { critical: 'red' , error: 'red' , warn: 'yellow' , info: 'green' , debug: 'blue' , }, }; const logger = createLogger({ levels: customLevels.levels, level: 'info' , format: format.combine( format.colorize({ all : true }), format.timestamp(), format.printf(({ timestamp, level, message } ) => `${timestamp} ${level} : ${message} ` ) ), transports: [new transports.Console(), new transports.File({ filename : 'app.log' })], }); winston.addColors(customLevels.colors); module .exports = logger;
customLevels: 사용자 지정 로깅 레벨과 해당 색상을 정의합니다.
winston.addColors: 로깅 레벨에 사용자 지정 색상을 적용합니다.
일일 로그 파일에 로깅하기
winston-daily-rotate-file
전송을 사용하여 매일 새 로그 파일을 만들 수 있습니다.
winston-daily-rotate-file
을 설치합니다:
1 npm install winston-daily-rotate-file
매일 로테이션 파일 전송을 구성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const { createLogger, format, transports } = require ('winston' );const DailyRotateFile = require ('winston-daily-rotate-file' );const logger = createLogger({ level: 'info' , format: format.combine( format.timestamp(), format.printf(({ timestamp, level, message } ) => `${timestamp} ${level} : ${message} ` ) ), transports: [ new transports.Console(), new DailyRotateFile({ filename: 'application-%DATE%.log' , datePattern: 'YYYY-MM-DD' , zippedArchive: true , maxSize: '20m' , maxFiles: '14d' , }), ], }); module .exports = logger;
DailyRotateFile: 지정된 날짜 패턴으로 매일 새 로그 파일을 만듭니다.
zippedArchive: 이전 로그 파일을 압축합니다.
maxSize: 회전하기 전 로그 파일의 최대 크기입니다.
maxFiles: 로그 파일을 보관할 수 있는 최대 일수입니다.
Express 애플리케이션에서 Winston 사용
Winston을 Express 애플리케이션에 통합하여 HTTP 요청 및 오류에 대한 로깅을 처리합니다.
Express를 설치합니다.
Winston으로 Express 서버를 설정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const express = require ('express' );const logger = require ('./logger' );const app = express();const PORT = process.env.PORT || 3000 ;app.use((req, res, next ) => { logger.http(`${req.method} ${req.url} ` ); next(); }); app.get('/' , (req, res) => { res.send('Hello, World!' ); }); app.use((err, req, res, next ) => { logger.error(err.message); res.status(500 ).send('Internal Server Error' ); }); app.listen(PORT, () => { logger.info(`Server is running on http://localhost:${PORT} ` ); });
HTTP 요청 로깅: 미들웨어는 logger.http
를 사용하여 들어오는 모든 HTTP 요청을 기록합니다.
오류 처리 미들웨어: logger.error
를 사용하여 오류를 기록합니다.
결론
Winston을 Node.js 애플리케이션에 통합하면 코드를 보다 효과적으로 디버그, 모니터링 및 유지 관리하는 데 도움이 되는 강력하고 유연한 로깅 시스템을 만들 수 있습니다. 콘솔, 파일 또는 외부 서비스에 로깅해야 하는 경우 Winston의 풍부한 기능 세트는 Node.js 로깅을 위한 탁월한 선택입니다.