1. winston 라이브러리를 이용해 로그 미들웨어를 구현합니다.
2. 게시판 프로젝트에 에러 처리 미들웨어를 적용합니다.
01. [게시판 프로젝트] 미들웨어
1) [게시판 프로젝트] 로그(Log) 미들웨어
로그 미들웨어(Log Middleware)는 클라이언트의 모든 요청 사항을 기록하여 서버의 상태를 모니터링하기 위한 미들웨어입니다. 문제 발생 시 빠르게 진단할 수 있도록 돕는 미들웨어입니다. 이를 통해 다음과 같은 작업이 가능합니다:
- 어플리케이션 모니터링
- 문제 진단
- 사용자 행동 분석
활용 방안
- 로그 라이브러리 사용
- Morgan, Winston 등과 같은 라이브러리를 이용하여 간편하게 로그를 기록하고 관리.
- 외부 모니터링 서비스
- 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 |