본문 바로가기
임시저장

Node.js 숙련주차 4.3 - 로그(Log) 미들웨어 - 게시판프로젝

by GREEN나무 2024. 11. 25.
728x90

1. winston 라이브러리를 이용해 로그 미들웨어를 구현합니다.
2. 게시판 프로젝트에 에러 처리 미들웨어를 적용합니다.

01. [게시판 프로젝트] 미들웨어

1) [게시판 프로젝트] 로그(Log) 미들웨어


로그 미들웨어(Log Middleware)는 클라이언트의 모든 요청 사항을 기록하여 서버의 상태를 모니터링하기 위한 미들웨어입니다. 문제 발생 시 빠르게 진단할 수 있도록 돕는 미들웨어입니다. 이를 통해 다음과 같은 작업이 가능합니다:

  • 어플리케이션 모니터링
  • 문제 진단
  • 사용자 행동 분석

활용 방안

  1. 로그 라이브러리 사용
    • Morgan, Winston 등과 같은 라이브러리를 이용하여 간편하게 로그를 기록하고 관리.
  2. 외부 모니터링 서비스
    • AWS CloudWatch, Datadog 등으로 로그 데이터를 수집 및 분석.
    • Datadog은 전문적인 지식 없이도 로그 수집 및 분석을 빠르게 구현 가능.

 middlewares/log.middleware.js 파일을 생성 후 winston 라이브러리를 이용하여 로그 미들웨어를 구현해보도록 하겠습니다!
[게시판 프로젝트] winston 설치 명령어

# yarn을 이용해 winston을 설치합니다.
yarn add winston


[게시판 프로젝트] 로그 미들웨어

// src/middlewares/log.middleware.js

import winston from "winston";

// winston.createLogger 를 이용해서 해당하는 winston logger를 구현합니다.
const logger = winston.createLogger({
    // 로그 레벨을 'info'로 설정합니다.
    // err, warn, debug 등을 출력
    level: "info",
    // 로그 포맷을 JSON 형식으로 설정합니다.
    format: winston.format.json(),
    //transports에는 어떤 형태로 format된 logger를 출력할 것인지에 대해 적습니다.
    transports: [
        new winston.transports.Console(), // 로그를 콘솔에 출력합니다.
    ],
});

// 1. 들어오고
export default function (req, res, next) {
    // 클라이언트의 요청이 시작된 시간을 기록합니다.
    const start = new Date().getTime(); // 2. 시작 시간을 정의하고

    // 4. 응답이 완료되면 로그를 기록하는 콜백함수가 돌아감
    res.on("finish", () => {
        // 콜백함수
        const duration = new Date().getTime() - start;
        logger.info(`Method: ${req.method}, URL: ${req.url}, Status: ${res.statusCode}, Duration: ${duration}ms`);
    });

    next(); // 3. 미들웨어가 동작하고
}

level

더보기

level로 사용할 수 있는 값은 로거가 정의한 로그 레벨에 따라 달라집니다. 주어진 인터페이스와 클래스에서 사용 가능한 레벨은 아래 두 그룹으로 나뉩니다:


1. NPM(Default) 로그 레벨

다음은 일반적으로 사용하는 NPM 스타일의 로그 레벨입니다. Logger 클래스의 error, warn, info 등과 같은 메서드에 해당하며, levels를 별도로 설정하지 않으면 기본으로 제공됩니다.

  • error: 심각한 에러 상황
  • warn: 경고 메시지
  • info: 일반 정보 메시지
  • http: HTTP 요청 로그
  • verbose: 상세 정보
  • debug: 디버깅 목적
  • silly: 개발 중 아주 세부적인 정보

2. Syslog 스타일 로그 레벨

Syslog 스타일 로그 레벨은 시스템 로그 수준에 적합하며, 명시적으로 설정한 경우 사용 가능합니다.

  • emerg: 긴급 상황 (시스템이 더 이상 작동하지 않는 경우)
  • alert: 즉각적인 조치가 필요한 상황
  • crit: 중요한 상황 (일부 구성 요소 실패 등)
  • error: 일반 에러 상황
  • warning: 경고
  • notice: 정상적이지만 주목할만한 상황
  • info: 정보 메시지
  • debug: 디버그 정보

3. 사용자 정의 레벨

LoggerOptions에서 levels를 정의하여 커스터마이징 가능합니다. 사용자 정의 예:

const customLevels = {
  fatal: 0,
  error: 1,
  warn: 2,
  info: 3,
  debug: 4,
  trace: 5,
};

위처럼 정의한 경우 fatal 같은 사용자 레벨도 사용 가능합니다.


레벨 설정 확인

Logger 인스턴스의 isLevelEnabled(level) 메서드로 특정 레벨의 활성 여부를 확인할 수 있습니다.


[코드스니펫] [게시판 프로젝트] 로그 미들웨어를 등록한 app.js

// src/app.js

import express from 'express';
import cookieParser from 'cookie-parser';
import LogMiddleware from './middlewares/log.middleware.js';
import UsersRouter from './routes/users.router.js';

const app = express();
const PORT = 3018;

app.use(LogMiddleware);
app.use(express.json());
app.use(cookieParser());
app.use('/api', [UsersRouter]);

app.listen(PORT, () => {
  console.log(PORT, '포트로 서버가 열렸어요!');
});



로그 레벨(level)은 로그의 중요도를 나타냅니다. 저희는 단순히 클라이언트의 요청 사항을 기록하기 위해 “info” 레벨을 사용하지만, “error”, “warn”, “debug"등 다양한 로그 레벨이 있으며, 특정 상황에 따라 출력하는 레벨을 다르게 구현할 수 있습니다.
로그 미들웨어는 클라이언트의 요청이 발생하였을 때, 가장 먼저 실행되어야 하는 미들웨어 입니다. 그렇기 때문에, app.use를 이용한 전역 미들웨어 중에서 가장 최상단에 위치한 것입니다.

 

2) [게시판 프로젝트] 에러 처리 미들웨어

express 문서 : https://expressjs.com/ko/guide/error-handling.html
에러 처리 미들웨어(Error Handling Middleware)는 Express.js에서 발생한 에러를 통합적으로 처리하기 위한 미들웨어 입니다.
이전 주차에서는 에러 처리 미들웨어를 구현해봤습니다. 이번에는 [게시판 프로젝트]에서도 같은 방식으로 에러 처리 미들웨어를 도입하겠습니다.
먼저, middlewares/error-handling.middleware.js 파일을 생성한 후, 회원 가입 API를 리팩토링하여 에러 발생 시, 에러 처리 미들웨어로 에러를 전달하도록 변경하겠습니다. 😎​
[코드스니펫] [게시판 프로젝트] 에러 처리 미들웨어

// src/middlewares/error-handling.middleware.js

export default function (err, req, res, next) {
  // 에러를 출력합니다.
  console.error(err);

  // 클라이언트에게 에러 메시지를 전달합니다.
  res.status(500).json({ errorMessage: '서버 내부 에러가 발생했습니다.' });
}


[코드스니펫] [게시판 프로젝트] 회원가입 API 에러 처리 리팩토링

// src/routes/users.router.js

/** 사용자 회원가입 API 에러 처리 미들웨어 **/
router.post('/sign-up', async (req, res, next) => {
  try {
    const { email, password, name, age, gender, profileImage } = req.body;
    const isExistUser = await prisma.users.findFirst({
      where: {
        email,
      },
    });

    if (isExistUser) {
      return res.status(409).json({ message: '이미 존재하는 이메일입니다.' });
    }

    // 사용자 비밀번호를 암호화합니다.
    const hashedPassword = await bcrypt.hash(password, 10);

    // Users 테이블에 사용자를 추가합니다.
    const user = await prisma.users.create({
      data: {
        email,
        password: hashedPassword, // 암호화된 비밀번호를 저장합니다.
      },
    });

    // UserInfos 테이블에 사용자 정보를 추가합니다.
    const userInfo = await prisma.userInfos.create({
      data: {
        userId: user.userId, // 생성한 유저의 userId를 바탕으로 사용자 정보를 생성합니다.
        name,
        age,
        gender: gender.toUpperCase(), // 성별을 대문자로 변환합니다.
        profileImage,
      },
    });

    return res.status(201).json({ message: '회원가입이 완료되었습니다.' });
  } catch (err) {
    next(err);
  }
});


[코드스니펫] [게시판 프로젝트] 에러 처리 미들웨어를 등록한 app.js

// src/app.js

import express from 'express';
import cookieParser from 'cookie-parser';
import LogMiddleware from './middlewares/log.middleware.js';
import ErrorHandlingMiddleware from './middlewares/error-handling.middleware.js';
import UsersRouter from './routes/users.router.js';

const app = express();
const PORT = 3018;

app.use(LogMiddleware);
app.use(express.json());
app.use(cookieParser());
app.use('/api', [UsersRouter]);
app.use(ErrorHandlingMiddleware);

app.listen(PORT, () => {
  console.log(PORT, '포트로 서버가 열렸어요!');
});


에러 처리 미들웨어는 클라이언트의 요청이 실패하였을 때, 가장 마지막에 실행되어야 하는 미들웨어 입니다. 따라서, app.use를 이용한 전역 미들웨어 중 가장 최하단에 위치한 것입니다.
에러 처리 미들웨어는 모든 에러를 관리하는 미들웨어, 서버 내부에서 발생한 에러를 상세하게 클라이언트에게 제공한다면 악의적인 사용자에게 공격의 표적이 될 수 있습니다. 
그렇기 때문에, 에러 처리 미들웨어에서는 “서버에서 에러가 발생하였습니다.”와 같은 추상적인 내용을 클라이언트에게 전달하도록 구현해야합니다.
설명
Default view

'임시저장' 카테고리의 다른 글

목차 만들기  (0) 2024.12.10
변수 일괄 수정  (0) 2024.12.09
스텐다드 IOS 7계층  (0) 2024.12.08
github 터미널 명령어 모음  (0) 2024.12.06
아ㅏㅏ  (0) 2024.12.06