pm2로 node.js 서비스를 올려서 사용하고 있는데 이제 슬슬 런칭 준비를 하면서 로그 백업이 필요할 거 같아서 세팅을 시작함
- 일별 로그 로테이션
- 용량 기반 분할
- 백업 관리
이런식으로 크게 세가지 카테고리로 설정을 하려고 한다.
1. 기본 디렉토리 구조 설정
# 백업 디렉토리 생성
mkdir -p /home/ec2-user/.pm2/logs/bak
나는 로그 폴더에 백업 폴더 하나 만들었음.. 백업 로그랑 현재 로그랑 분리하고 싶었기 때문에..
2. pm2-logrotate 모듈 설치 및 설정
# 모듈 설치
pm2 install pm2-logrotate
이렇게 설치해주면,
이렇게 설치가 되서 하단에 모듈에 pm2-logrotate가 추가된 걸 확인할 수 있다.
그 위에는 테스트 서버 올려둔 거라서 핑크색 박스로 이름 가림 ㅎ..
그리고 이제 로테이션 설정을 어케할지 설정을 해줘야겠지
# 로테이션 설정
pm2 set pm2-logrotate:rotateInterval '0 15 * * *' # 한국 시간 00:00 (UTC 15:00)
pm2 set pm2-logrotate:TZ 'Asia/Seoul' # 타임존 설정
pm2 set pm2-logrotate:retain 180 # 180일간 보관
pm2 set pm2-logrotate:dateFormat 'YYYY-MM-DD' # 날짜 형식(일별 저장할거라 날짜까지만)
pm2 set pm2-logrotate:max_size '100M' # 파일 크기 제한
pm2 set pm2-logrotate:rotateFilePath '.pm2/logs/bak' # 백업 저장 경로
pm2 set pm2-logrotate:workerInterval '30' # 작업 주기(30초 단위로 파일 크기 체크)
pm2 set pm2-logrotate:rotateModule 'true' # 모듈 로그도 로테이션
마지막 모듈 로그는 뭔말이냐면 모듈로그도 냅두면 로그가 계속 커지기 때문에 쟤도 그냥 로테이션에 추가시키기로 설정함...
3. 로그 압축 스크립트 생성
compress-log.sh 파일 생성해서 내용을 작성해줌.. 파일명은 머.. 맘대로 하세여..
당연히 bucket 이름 등은 본인의 s3 버킷으로 잘.. 써주세요
내 블로그는 오른쪽 마우스 버튼 금지라 파일로도 올려드림미다 쓰실 분 쓰시길..
#!/bin/bash
echo "로그 압축 및 S3 백업 프로세스 시작..."
# AWS 인증 체크
if ! aws sts get-caller-identity &> /dev/null; then
echo "❌ AWS 인증 실패: IAM 역할 또는 액세스 키를 확인해주세요"
exit 1
fi
echo "✅ AWS 인증 성공"
# 30일 이상 된 로그 파일들 찾기
log_files=$(find .pm2/logs/bak -name "*.log" -mtime +30)
# 로그 파일이 있는 경우에만 처리
if [ ! -z "$log_files" ]; then
echo "📁 30일 이상 된 로그 파일 발견"
# 파일들에서 날짜만 추출하여 가장 오래된 날짜와 최신 날짜 찾기
dates=$(echo "$log_files" | while read file; do
basename "$file" | grep -o '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}'
done | sort)
start_date=$(echo "$dates" | head -n 1)
end_date=$(echo "$dates" | tail -n 1)
# YYYY-MM-DD 형식을 YYMMDD 형식으로 변환
start_short=$(echo $start_date | sed 's/^20\([0-9]\{2\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\1\2\3/')
end_short=$(echo $end_date | sed 's/^20\([0-9]\{2\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\1\2\3/')
# 기본 파일명 가져오기 (app-error 등)
base_name=$(basename $(echo "$log_files" | head -n 1) | sed 's/-[0-9].*$//')
# 새 압축 파일명 생성
new_filename="${base_name}_${start_short}-${end_short}.gz"
echo "📦 압축 파일 생성 중: $new_filename"
# 모든 로그 파일을 하나의 파일로 합치고 압축
if cat $log_files | gzip > ".pm2/logs/bak/$new_filename"; then
echo "✅ 로그 압축 성공: $new_filename"
# S3 업로드 시도
if aws s3 cp ".pm2/logs/bak/$new_filename" "s3://your-bucket/logs/$new_filename"; then
echo "✅ S3 업로드 성공"
# 압축과 S3 업로드가 모두 성공한 경우에만 원본 파일 삭제
echo "$log_files" | xargs rm
echo "🗑️ 원본 로그 파일 삭제 완료"
# S3에 업로드된 파일 확인
if aws s3 ls "s3://your-bucket/logs/$new_filename" &> /dev/null; then
echo "✅ S3 파일 존재 확인 완료"
else
echo "⚠️ 경고: S3 파일 확인 실패"
fi
else
echo "❌ S3 업로드 실패, 원본 파일 유지"
fi
else
echo "❌ 로그 압축 실패"
# 압축 실패시 임시 파일 삭제
rm -f ".pm2/logs/bak/$new_filename"
fi
else
echo "📝 처리할 30일 이상 된 로그 파일이 없습니다"
fi
echo "로그 압축 및 S3 백업 프로세스 완료"
이 스크립트는...
1. 30일 이상 된 로그 파일 탐색
2. 발견된 로그들을 날짜 기준으로 묶어서 하나의 압축 파일로 생성
3. 압축 파일명에 로그 기간 포함 (예: app-error_240301-240331.gz)
4. AWS S3에 압축 파일 업로드
5. 업로드 성공 시 원본 로그 파일 삭제
이런 식의 로직이고,
아래와 같은 정보들을 체크함
- AWS 인증 상태 사전 확인(이거는 AWS 콘솔에서 내 EC2에 S3 full Access 권한을 미리 줬음.. 그래서 인증절차 없이 그냥 확인만..)
- 압축 성공 여부 확인
- S3 업로드 성공 여부 확인
- 각 단계별 실패 시 원본 파일 보존
4. 자동화를 위한 crontab 설정
크론탭은.. 스케쥴러임.. 주기적으로 뭐 돌려야할 때 유용함..
나는 주기적으로 저 스크립트가 실행이 되야하기 때문에 크론탭에 등록함
# 크론탭 설치 (root 권한 필요)
sudo yum install -y cronie
# 크론 서비스 시작 및 자동 시작 설정
sudo systemctl start crond
sudo systemctl enable crond
# 크론 서비스 상태 확인
crontab -e
# 편집기가 열리면 다음 내용 추가 (매일 한국 새벽 1시에 실행하기 위해 서버시간은 UTC라서 16시로 세팅)
0 16 * * * /home/ec2-user/.pm2/compress-logs.sh
# 크론탭 목록 확인
crontab -l
# 실행권한 필요하면..
chmod +x /home/ec2-user/.pm2/compress-logs.sh
# 로그는 여기서 확인
cat /var/log/cron
끝!
정리해보자면,
일별 로테이션
매일 한국 시간 00:00에 새로운 로그 파일 생성
이전 로그는 날짜를 붙여서 bak 디렉토리로 이동
파일명 예시: app-error-2024-04-02.log
용량 기반 분할
로그 파일이 100MB 초과시 자동으로 분할
분할 파일명 예시:
app-error-2024-04-02.log
app-error-2024-04-02-1.log
app-error-2024-04-02-2.log
자동 압축
30일 이상 된 로그는 자동으로 gzip 압축
매일 새벽 1시에 압축 작업 실행
압축 파일명 예시: app-error-2024-03-25.log.gz
S3 백업
압축된 로그 파일을 S3에 자동 백업
S3에 성공적으로 업로드된 180일 이상 된 로그는 로컬에서 삭제