본문 바로가기
Programming/JS & TS

[Back-End] Web 운영을 위한 로그 관리

by 강한수달 2022. 1. 5.

로그

- 로그는 시스템을 운영할 때 발생하는 모든 데이터를 의미함

- 시스템 운영 시 예기치 못한 오류, 치명적인 장애가 발생했을 때 그 원인을 추적하기 위해 로그 관리가 필요함

 

로그 관리 모듈, Winston

Winston.js

- 로그를 관리하는데 사용하는 대표적인 Node.js 모듈

 

로그 레벨

- 각 로그별 중요도를 나타내기 위해 사용하는 로그 분류 기준

- 가장 중요한 것부터 덜 중요한 순으로 오름차순 정렬된 값

- RFC5424 의 심각도 순서를 차용함

 

Winston 에서의 로그 레벨[1]

[1] Github, Winston.js Documentation

 

설치 방법

npm install winston

 

예제 코드

// logger.js
const winston = require('winston');
const winstonDaily = require('winston-daily-rotate-file');
const appRoot = require('app-root-path');
const process = require('process');

const logDir = `${apRoot}/logs`;

const {combine, timestamp, label, printf} = winston.format;
const logFormat = printf(({level, message, label, timestamp}) => {
  return `${timestamp} [${label}] ${lebel}: ${message}`; // 로그 출력 포맷 정의
 });
 
 const logger = winston.createLogger({
   format: combine(
     label({
       label: 'System Name'
     }),
     timestamp({
       format: 'YYYY-MM-DD HH:mm:ss'
     }),
     logFormat
   ),
   transports: [
     new winstonDaily({  // info 레벨 로그를 저장할 파일 설정
       level: 'info',
       datePattern: 'YYYY-MM-DD',
       dirname: logDir,
       filename: `%DATE%.log`,
       maxFiles: 30,  // 최근 30일치 로그 파일만 저장
       zippedArchiv: true
     }),
     new winstonDaily({  // error 레벨 로그를 저장할 파일 설정
       level: 'error',
       datePattern: 'YYYY-MM-DD',
       dirname: logDir,
       filename: `%DATE%.error.log`,
       maxFiles: 30, // 최근 30일치 로그 파일만 저장
       zippedArchiv: true
     })
   ],
   exceptionHandlers: [  // uncaughtException 발생 시
     new winstonDaily({  // error 레벨 로그를 저장할 파일 설정
       level: 'error',
       datePattern: 'YYYY-MM-DD',
       dirname: logDir,
       filename: `%DATE%.exception.log`,
       maxFiles: 30, // 최근 30일치 로그 파일만 저장
       zippedArchiv: true
     })
   ]
 })
 
 // 운영 환경이 아닌 경우 콘솔로도 로그 출력
 if (process.env.NODE_ENV !== 'production') {
   logger.add(new winston.transports.Console({
     format: winston.format.combine(
       winston.format.colorize(),   // 가독성을 위해 로그에 색상을 넣어 출력함
       winston.format.simple()   // 간단한 포맷으로 출력
     )
   }));
 }
 
 module.exports = logger;
// app.js
import * as express from 'express'
import * as http from 'http'
import logger from './logger'

// Shutdown codes
const errShutdown = async (server: http.Server, err?: Error) => {
  logger.error(`Stopping server with error: ${err}`)
  await server.close()
  process.exit(1)
}

async function runServer() {
  const app = express()
  const server = app.listen(5000, () => {
    logger.info('Server app listening on port 5000!')
  })
  try {
  } catch (e) {
    errShutdown(server, e)
    throw e
  }
}
runServer()
  .then(() => {
    logger.info('run succesfully')
  })
  .catch((ex: Error) => {
    logger.error('Unable run:', ex)
  })

 

 

# Reference

[1] Github, Winston.js Documentation

  URL : https://github.com/winstonjs/winston

[2] Github, seungwongo/node-project

  URL : https://github.com/seungwongo/node-project

[3] netlify, kooku, winston으로 log 관리하기

  URL : https://kooku.netlify.app/node.js/winston으로-log-관리하기/

 

댓글