오늘의 할 일
- 로그 관리
- 예외 처리
1. 로그관리
외부 로깅 라이브러리인 winston을 사용하기 위해 winston 설치
logger.js 작성
const winston = require("winston");
const logger = winston.createLogger({
// 출력 형식 정의
transports: [
new winston.transports.Console(), // 콘솔 출력: 개발 중 디버깅에 사용됨
new winston.transports.File({ filename: "app.log" }), // 파일 출력: 실제 운영 환경에서 로그 관리
],
// 로그 형식 지정
format: winston.format.combine(
// combine을 사용하여 여러 형식을 조합할 것을 배열로 정의
winston.format.timestamp(), // 시간 출력
winston.format.colorize(), // 색상 출력
winston.format.json(), // JSON 형식으로 출력
winston.format.simple() // ${info.level}: ${info.message} 형식으로 출력
),
});
module.exports = logger;
로그파일 사용(세션모듈)
var UserRealm = require("../db/realm");
var logging = require("../util/logger"); // 로그 모듈
function session(req, res, next) {
logging.info("사용자 인증 요청");
// 헤더에서 이메일과 토큰 추출
const email = req.headers.email;
const token = req.headers.token;
if (!email || !token) {
logging.error("이메일과 토큰을 확인해주세요.");
res.status(401).send({ message: "이메일과 토큰을 확인해주세요." });
return 0;
}
try {
// 이메일 && 토큰이 true인 사용자 찾기
const user = UserRealm.objects("User").filtered(
`email = "${email}" AND token = "${token}"`
)[0];
if (user && new Date() > user.tokenExp) {
logging.error("토큰 만료");
return 0;
} else {
logging.info("사용자 인증 성공", { user: user });
// 토큰 만료시간
const tokenExp = new Date();
tokenExp.setDate(tokenExp.getDate() + 30);
// realm에 토큰 만료시간 갱신
UserRealm.write(() => {
user.tokenExp = tokenExp;
});
return user;
}
} catch (error) {
logging.error("사용자 인증 실패", error);
return 0;
}
}
module.exports = session;
로그 확인
winston에서 제공하는 timestamp 가 대한민국 기준이 아니라서 moment-timezone 라이브러리를 설치하여 형식을 바꿔줘야함
moment-timezone 설치
logger.js 파일 수정
const winston = require("winston");
const moment = require("moment-timezone");
moment.tz.setDefault("Asia/Seoul"); // 한국 시간으로 설정
const logger = winston.createLogger({
// 출력 형식 정의
transports: [
new winston.transports.Console(), // 콘솔 출력: 개발 중 디버깅에 사용됨
new winston.transports.File({ filename: "app.log" }), // 파일 출력: 실제 운영 환경에서 로그 관리
],
// 로그 형식 지정
format: winston.format.combine(
// combine을 사용하여 여러 형식을 조합할 것을 배열로 정의
winston.format.timestamp({
format: moment().format("YYYY-MM-DD HH:mm:ss"), // 시간 형식 지정
}), // 시간 출력
winston.format.colorize(), // 색상 출력
winston.format.json(), // JSON 형식으로 출력
winston.format.simple() // ${info.level}: ${info.message} 형식으로 출력
),
});
module.exports = logger;
로그 확인
로그 Level
error | 에러 메시지 |
warn | 경고 메시지 |
info | 정보 메시지 |
debug | 디버그 메시지 |
verbose | 자세한 메시지 |
2. 예외처리
try ~ catch 로 에러가 발생했을 때 error 그 자체를 로그에 나오게 되어 있었음
이 경우 가독성이 떨어지며 구체적인 에러 파악을 위한 시간을 많이 써야할 수 있음
아래와 같이 구체적인 상황마다 에러 발생 이유를 남겨주는 형태로 수정
/* POST 계정 추가. */
// todo: 이메일 중복체크
router.post("/", function (req, res, next) {
logging.info("POST/ 계정 추가", { body: req.body });
var email = req.body.email;
var password = req.body.password;
var name = req.body.name;
var tel = req.body.tel;
try {
// 이메일 중복체크
const existUser = account.findUserByEmail(email);
if (existUser) {
logging.error("이메일 중복", { email: email });
res.status(409).send(response.fail(409, "이메일 중복")); // 409: Conflict
} else {
UserRealm.write(() => {
UserRealm.create("User", {
email: email,
password: password,
name: name,
tel: tel,
toeken: "default",
date: new Date(),
tokenExp: new Date(),
});
});
res.status(201).send(response.success(201, "계정 추가 성공"));
}
} catch (error) {
logging.error("계정 추가 실패", { error: error });
res.status(500).send(response.fail(500, "계정 추가 실패"));
}
});
그 결과 로그확인 시 가독성이 좋고, 어디서 에러가 발생했는지 한번에 파악할 수 있음
'Node.js' 카테고리의 다른 글
[Node.js] 노드 Express 라우터(Router) (0) | 2023.11.24 |
---|---|
[Node.js] 계정관리 서버 프로젝트 4 (0) | 2023.11.17 |
[Node.js] exress 프로젝트 로그 관리 방법 (0) | 2023.11.15 |
[Node.js] 계정관리 서버 프로젝트 2 (0) | 2023.11.15 |
[Node.js] 계정관리 서버 프로젝트 1 (0) | 2023.11.14 |