
로그와 에러 처리는 애플리케이션 운영에 있어 핵심적인 역할을 한다. 이 포스트에서는 Node.js와 Express 기반 애플리케이션에서 Morgan을 사용한 요청 로그와 에러 처리 미들웨어를 어떻게 구현하는지, 그리고 그 각각의 역할을 알아보겠다.
Morgan은 HTTP 요청에 대한 로그를 남기는 미들웨어로, 애플리케이션에 어떤 요청이 들어오는지, 어떤 상태로 응답하는지 등을 쉽게 확인할 수 있다. 이를 통해 애플리케이션의 성능을 모니터링하고, 문제 발생 시 신속하게 대응할 수 있다.
morganMiddleware.js) morganMiddleware.js 에서는 다음과 같이 Morgan을 설정하고 있다.
import morgan from "morgan";
import dotenv from "dotenv";
import momentTimeZone from "moment-timezone";
import {logger} from "#util/logger.js";
dotenv.config();
const timeZone = "Asia/Seoul";
// 날짜 형식 정의
morgan.token("date", (req, res, tz) => {
return momentTimeZone().tz(tz).format("YYYY-MM-DD HH:mm:ss");
});
// 로그 포맷 설정 함수
function format() {
const productionFormat = ':remote-addr - :remote-user [:date[' + timeZone + ']] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
const developmentFormat = ':remote-addr - :remote-user [:date[' + timeZone + ']] ":method :url HTTP/:http-version" :status :res[content-length] - :response-time ms';
return process.env.NODE_ENV === "production" ? productionFormat : developmentFormat;
}
// 로그 출력 스트림 설정 (Winston을 통해 기록)
const stream = {
write: (message) => {
logger.info(`SERVER LOG: ${message.trim()}`);
}
}
// 스킵 조건 설정 (production에서는 400 이하 상태 코드만 스킵)
const skip = (_, res) => {
if (process.env.NODE_ENV === "production") {
return res.statusCode < 400;
}
return false;
}
// Morgan 미들웨어 생성 및 내보내기
export const morganMiddleware = morgan(format(), {stream, skip});
format() 함수는 현재 환경에 따라 로그 포맷을 결정한다. 개발 환경에서는 요청과 응답 시간까지 포함된 포맷을 사용하고, 프로덕션 환경에서는 기본적인 요청 정보만 기록한다.moment-timezone을 이용해 "Asia/Seoul" 타임존으로 설정하고, 로그에 포함한다.logger.info()를 사용해 Morgan 로그를 기록한다.morganMiddleware)를 Express 애플리케이션에서 사용할 수 있도록 내보낸다.애플리케이션이 정상적으로 동작하지 않는 상황에서, 에러 처리는 사용자 경험을 보호하고 문제를 추적하는 데 필수적이다. 에러 처리 미들웨어는 모든 요청이 처리된 이후에 실행되며, 발생한 에러를 포착하고 적절하게 응답한다.
app.js) app.js 에서는 아래와 같이 에러 처리 미들웨어를 구현하고 있다.
app.use((err, req, res, next) => {
logger.error(`Middleware Error Process : ${err}`);
res.status(500).json({
success: false,
timestamp: wbLib.getToday(),
path: req.originalUrl,
method: req.method,
message: '서버에 문제가 발생하였습니다. ',
errorCode: '500_INTERNAL_SERVER_ERROR!!',
});
});
에러 처리 흐름
err, req, res, next)를 받는 에러 처리용 미들웨어이다.에러 로그 기록
logger.error()를 통해 발생한 에러 내용을 기록한다. 이를 통해 운영 중 어떤 문제가 발생했는지 추적할 수 있다.에러 응답
timestamp: 에러 발생 시간을 기록하며, 이는 wbLib.getToday() 함수를 통해 가져온다.wbLib.getToday()는 현재 시간을 지정한 스트링 형식으로 리턴하는 함수이며 별도로 관리하고있는 라이브러리의 함수이다.wbLib.getToday()// wbLib.js
export function getToday() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
path, method: 요청 경로와 HTTP 메서드를 포함해 어떤 요청에서 에러가 발생했는지 쉽게 추적할 수 있다.message와 *errorCode를 통해 사용자에게 친절한 에러 메시지를 제공한다.이제 두 미들웨어가 어떻게 함께 동작하는지 알아보자.
이번 포스트에서는 Node.js 애플리케이션에서 Morgan과 에러 처리 미들웨어가 어떻게 동작하고 설정되어 있는지 살펴보았다. 이 두 미들웨어는 각각 요청 로그 관리와 에러 처리에 중요한 역할을 하며, 함께 사용함으로써 애플리케이션의 안정성을 높이고 문제 발생 시 신속하게 대응할 수 있게 돕는다.
자료참조 : inpa dev
https://inpa.tistory.com/entry/EXPRESS-%F0%9F%93%9A-morgan-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4