이번에 내가 꾸린 Cineps 프로젝트 팀에 합류하신 개발자님에게 로그 관리에 대한 필요성에 대한 언급과 함께 로그 관리 시스템 구축을 의뢰했는데 너무 잘해주셔서 나도 따라 공부해보려고 한다.
log가 왜 필요해?
Exception이 발생 했을 때 error log를 남기는 것이 중요하다. 뭔가 일이 터졌는데 어쩌다 이렇게 error가 났었는지 기록으로 남아야 한다. 그래야 나중에라도 내가 무엇을 잘못 한 건지 분석을 해 볼테니 말이다. 프로그램이 정상적으로 작동하지 않고 갑자기 꽥 죽어 버렸는데 error log는 남아 있지 않다면 참으로 난감해진다. 누가 돌연사 해 버렸는데 부검 할 의사도 없는 상황인 것이다.
출처 : https://velog.io/@mowinckel/%EC%95%84%EB%AC%B4%EB%8F%84-%EA%B0%80%EB%A5%B4%EC%B3%90-%EC%A3%BC%EC%A7%80-%EC%95%8A%EB%8A%94-%EA%B2%83#-log
java에서는 logging 라이브러리를 주로 사용하는데 node.js 진영에선 배포 클러스터 구축시 사용하는 pm2의 모듈에 로그를 관리하는 툴이 있어 그것을 사용하면 된다.
물론 로그를 남겨주는 Sentry 같은 툴을 사용하는 것이 생산성, 편리성에 있어 훨씬 좋겠지만 여기서는 직접 pm2를 이용하기로 했다.
log rotation
어플리케이션을 서버에서 실행하고 서비스를 하기 시작하면 날이 갈 수록 로그가 쌓여가기 시작한다. 1년 동안 서비스를 했다면 365개의 파일이 생기는 것이다.
log는 텍스트 로만 이루어져 있지만 이게 은근히 용량을 많이 차지한다. 인기 서비스라면 하루에 수천만 개의 로그가 쌓이고 사용자까지 많다면 억대로 쌓이는 경우도 봤다. 로그를 자세히 남긴다면 하루치 로그가 100GB를 넘는 것은 일도 아니다. 대형 포털에서 일하게 된다면 반드시 그럴 것이다.
출처 : https://velog.io/@mowinckel/%EC%95%84%EB%AC%B4%EB%8F%84-%EA%B0%80%EB%A5%B4%EC%B3%90-%EC%A3%BC%EC%A7%80-%EC%95%8A%EB%8A%94-%EA%B2%83#-log
아직 Cineps는 로그 파일이 70Mb밖에 안되지만, 미리미리 관리를 시작하는 것이 좋다고 판단했다.
Cron 까지 붙여서 특정 시간대에 로그를 지워주는 작업도 하면 금상첨화!
linux 자체적으로 Cron job을 만들 수도 있겠지만 pm2 log-rotate 모듈을 통해서 log 비워주는 작업을 진행할수도 있다.
pm2 log management
자세한 내용, 더 커스터마이징하고 싶은 내용은 직접 문서를 참고하자.
pm2.keymetrics.io/docs/usage/log-management/#size-limited-log-rotation
(1) CLI
When running pm2 start app.js [OPTIONS] you can pass any of this options to the CLI:
-l --log [path] specify filepath to output both out and error logs
-o --output <path> specify out log file
-e --error <path> specify error log file
--time prefix logs with standard formated timestamp
--log-date-format <format> prefix logs with custom formated timestamp
--merge-logs when running mutiple process with same app name, do not split file by id
지금까지 써온 pm2 명령어들을 모아보니 아래와 같은 명령어을 찾을 수 있었습니다.
pm2 start app.js -e err.log -o out.log
error 로그는 현재경로/err.log, out 로그는 현재경로/out.log 에 저장하라는 거네요
따로 설정하지 않으면 "현재유저/.pm2/logs" 에 저장됩니다.
개인적으론, 기본값으로 계속 써와서 그런가 기본 경로가 편하네요.
(2) flush
수작업으로 로그를 날릴때 쓴다.
pm2 flush
주의하실 점이 그냥 ~/.pm2/logs/*를 지워버린다는 개념이 아니라는 겁니다.
pm2 flush는 지금 사용하고 있는 로그파일만 지워줍니다. "flushes only pm2.log and logs of active processes."
rotated된 log까지 지워버리고 싶다면 그냥 rm rf ~/.pm2/logs/* 를 날려줍시다.
pm2-logrotate
주기적으로 log가 쌓이지 않게 지워줘야겠죠?
You can also install pm2-logrotate to automatically rotate and keep all the logs file using a limited space on disk.
만약 pm2-logrotate를 설치하지 않고 pm2만 이용하게 되면 로그 파일은 한개만 생성되고 계속 사이즈가 증량되는 방식으로 로그가 쌓입니다. 소규모에서는 오히려 이게 편할 수 있겠죠.
github.com/keymetrics/pm2-logrotate
(1) 설치
pm2 install pm2-logrotate
NOTE: the command is pm2 install NOT npm install
pm2 모듈이라는 점에서 주의하셔야 합니다. 얼마나 관련 문의가 많았으면 github에 경고 문구까지 달아뒀네요
설치 즉시 기본값이 적용된 rotate가 돌기 시작합니다. pm2 list로 확인해보세요!
설치하면 다음과 같은 화면을 보실 수 있습니다.
기본값으로 설정된 값들을 확인하실 수 있습니다.
- max_size (Defaults to 10M): 파일 사이즈가 해당 값보다 크게될 경우 rotate 합니다. worker가 해당 용량을 칼같이 지키는 건 아니라 제한 용량을 살짝 넘기고서 rotate하는 경우도 있다고 하네요. 반드시 특정 용량 아래로 로그 파일을 나눠야 할 경우 보수적으로 잡는 것이 좋아보입니다.
값은 10G, 10M, 10K 등과 같이 줄 수 있답니다. 저희 서비스인 Cineps에선 기본값인 10M가 적절해보입니다. - retain (Defaults to 30 file logs): rotated 된 로그 파일을 최대 몇개까지 가지고 있을 것인지에 대한 설정입니다. 기본값은 30이디 log 파일은 30개까지 존재하게 되겠네요.
- compress (Defaults to false): rotated 된 로그를 gzip으로 압축할 것인가를 묻습니다. 로그의 양이 많아지면 자동으로 gzip으로 압축하게끔 설정하는 것이 좋을테지만, 현재는 내버려 두도록 합시다.
- dateFormat (Defaults to YYYY-MM-DD_HH-mm-ss) : 네 말 그대로 ㅎ
- rotateModule (Defaults to true) : Rotate the log of pm2's module like other apps
- workerInterval (Defaults to 30 in secs) : You can control at which interval the worker is checking the log's size (minimum is 1)
- rotateInterval (Defaults to 0 0 * * * everyday at midnight): cron job 입니다. 기본값이 자정마다 rotate를 돌리기로 되어 있네요. retain 값이 30이고, rotateInterval이 매 자정마다 이루어지므로 1달이면 로그 파일이 꽉 차겠군요.
- TZ (Defaults to system time): This is the standard tz database timezone used to offset the log file saved. For instance, a value of Etc/GMT+1, with an hourly log, will save a file at hour 14 GMT with hour 13 (GMT+1) in the log name.
cron에 대해서는 별도로 공부한 적이 있지만, 다시 첨부하겠습니다.
* * * * * *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ |
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ └─────────────── hour (0 - 23)
│ └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, OPTIONAL)
(2) pm2-logrotate 설정을 변경하고 싶다면
pm2 set pm2-logrotate:<param> <value>
[예시들]
// force rotate every minute
pm2 set pm2-logrotate:rotateInterval '*/1 * * * *'
// 1KB
pm2 set pm2-logrotate:max_size 1K
// compress logs when rotated
pm2 set pm2-logrotate:compress true
참고한 글)
개발자님이 블로그를 갓 시작하셨다는데 글도 깔끔하고 디자인도 좋아서 읽을 맛이 난다!
'Node, Nest, Deno > 🚀 Node.js (+ Express)' 카테고리의 다른 글
fs 모듈로 Binary 파일 처리부터 Buffer와 Stream까지 (3) | 2021.01.28 |
---|---|
node.js에서 child_process로 다른 프로세스 생성하기 (0) | 2021.01.27 |
nginx(reverse-proxy), node에서 이미지 업로드 중 request entity too large 에러 (0) | 2020.12.08 |
express 보안 우수 사례를 참고한 보안 강화 (0) | 2020.11.23 |
동기 I/O 와 비동기 I/O 의 성능 차이 + Node.js를 쓸 이유가 없다? (0) | 2020.11.22 |