[시스템 관리] 04. 로그 관리 - 로그 로테이션
카테고리: SYS_MGMT
🔔 로그 로테이션 - logrotate
로그 정보가 계속 쌓이면 파일 용량문제로 시스템에 문제가 생길수가 있으므로 사전에 저장 기간 및 저장 방법 설정하여 원할한 서버 관리, 운영을 하기 위해 설정하는 기능이 logrotate이다.
■ logrotate 설치
# CentOS (RHEL 계열)
yum -y install logrotate
# Ubuntu (Debian 계열)
apt -y install logrotate
■ logrotate 파일 구조
| 종류 | 내용 |
|---|---|
| /usr/sbin/logrotate | logrotate 데몬 위치 및 데몬 프로그램 |
| /etc/logrotate.conf | logrotate 데몬 설정 파일 |
| /etc/logrotate.d | logrotate를 적용할 프로세스/데몬 설정 파일 |
| /var/lib/logrotate.status | logrotate 한 작업 내역을 보관한 파일 |
| /etc/cron.daily/logrotate | logrotate는 주기적으로 실행되어야 한다, cron에 의해 일 단위로 실행이됨 |
■ logrotate 설정 항목
| 종류 | 내용 |
|---|---|
| compress | 로테이션된 로그를 압축 |
| nocompress | 로테이션된 로그를 압축안함 |
| create [퍼미션] [사용자명] [그룹명] | 로테이션한 다음에 새로운 빈 로그 파일을 생성 (파일의 퍼미션, 사용자명, 그룹명 지정할 수 있음) |
| nocreate | 새로운 빈 로그 파일을 생성하지 않는다. |
| daily | 매일 로그파일을 로테이션 진행 (정확한 일시는 cron에 의존) |
| weekly | 매주 로그파일을 로테이션 진행 (정확한 일시는 cron에 의존) |
| monthly | 매월 로그파일을 로테이션 진행 (정확한 일시는 cron에 의존) |
| ifempty | 로그 파일이 비어 있더라도 로테이션 진행 |
| notifempty | 로그 파일이 비어있는 경우 로테이션하지 않음 |
| missingok | 로그 파일이 존재하지 않더라도 오류를 내보내지 않는다. |
| nomissingok | 로그 파일이 존재하지 않으면 오류를 내보낸다. |
| dateext | 로그 파일명에 날짜 확장자를 추가 |
| olddir 디렉터리명 | 지정된 디렉터리 내에 로테이션된 로그를 저장 |
| noolddir | 로테이션 대상인 로그와 동일한 디렉터리에 로테이션된 로그를 저장 |
| rotate n | 지정된 횟수만큼만 로테이션 진행 |
| size n | 로그 파일이 저장한 파일 크기 이상이면 로테이션 진행 |
| sharedscripts | 복수로 지정한 로그 파일에 대해 postrotate 또는 prerotate로 기술된 명령을 1회만 실행 |
| postrotate - endscript | postrotate와 endscript 사이에 기술된 명령을 로그 로테이션한 다음에 실행 |
| prerotate - endscript | prerotate와 endscript 사이에 기술된 명령을 로그 로테이션 전에 실행 |
| include /etc/logrotate.d | 해당 디렉터리에 있는 개별 데몬/프로세스 설정 파일을 포함 |
■ logrotate 사용 예시
▶ logrotate - httpd 설정
$ cat <<EOF > /etc/logrotate.d/httpd
/var/log/httpd/*log {
missingok
notifempty
sharedscripts
postrotate
/bin/systemctl reload httpd > /dev/null 2> /dev/null || true
endscript
}
EOF
▶ logrotate - nginx 설정
$ vim /etc/logrotate.d/nginx
/var/log/nginx/*log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
▶ logrotate 테스트
| 옵션 | 내용 |
|---|---|
| -d | 디버그 실행 |
| -v | 상세 표시 |
| -f | 강제로 실행 |
| -m | 메일 송신을 위한 지정, (ex: -m=/bin/mail) |
| -s | 상태 파일의 경로 지정, (ex: -s=/var/lib/logrotate.status) |
logrotate의 실행 결과가 정상적이면 아래와 같은 상세 정보가 출력되고, “log does not need rotating”가 출력되었으므로 로그 로테이션이 필요 없다고 판단한 것이다.
$ logrotate -dv /etc/logrotate.d/nginx
reading config file /etc/logrotate.d/nginx
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/nginx/*log after 1 days (52 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
Creating new state
Now: 2023-07-28 21:57
Last rotated at 2023-07-28 21:00
log does not need rotating (log has been already rotated)
considering log /var/log/nginx/error.log
Creating new state
Now: 2023-07-28 21:57
Last rotated at 2023-07-28 21:00
log does not need rotating (log has been already rotated)
not running postrotate script, since no logs were rotated
위와 같이 로그 로테이션이 필요 없다고 나타나는 경우는 오류가 있거나 로그 파일이 존재하지 않는 경우를 제외하면 로그 로테이션을 마지막으로 실행한 후에 아직 1일 이상 경과하지 않았기 때문인 경우가 많다.
이런 경우에는 로그 로테이션 설정 파일의 내용에 오류가 없는지 확인할 수 있도록 logrotate 상태 파일(/var/lib/logrotate.status)의 최종 로그 로테이션 실행 일자를 바꾼 다음 확인해 보는게 좋다.
# 변경 전
$ cat /var/lib/logrotate/logrotate.status
~(생략)~
"/var/log/nginx/access.log" 2023-7-28-22:0:0
~(생략)~
# 변경 후 -> 일자를 하루 전으로 수정하고 저장
$ cat /var/lib/logrotate/logrotate.status
~(생략)~
"/var/log/nginx/access.log" 2023-7-27-22:0:0
~(생략)~
아래와 같이 로그 로테이션이 필요하다고 판단하여 “log need rotating”이 출력된다.
$ logrotate -dv /etc/logrotate.d/nginx
reading config file /etc/logrotate.d/nginx
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/nginx/*log after 1 days (52 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
Now: 2023-07-28 22:47
Last rotated at 2023-07-27 22:00
log needs rotating # <- (해당 부분)
considering log /var/log/nginx/error.log
Now: 2023-07-28 22:47
Last rotated at 2023-07-28 22:00
log does not need rotating (log has been already rotated)
rotating log /var/log/nginx/access.log, log->rotateCount is 52
dateext suffix '-20230728'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
set default create context to system_u:object_r:httpd_log_t:s0
previous log /var/log/nginx/access.log.1 does not exist
~(생략)~
설정이 오류(단순히 ‘aaaa’를 /etc/logrotate.d/nginx 옵션에 추가)가 있다면 아래와 같이 오류를 출력한다.
$ logrotate -dv /etc/logrotate.d/nginx
WARNING: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/nginx
error: /etc/logrotate.d/nginx:2 unknown option 'aaaa' -- ignoring line # <- (해당 부분)
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/nginx/*log after 1 days (52 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
Now: 2023-07-28 22:51
Last rotated at 2023-07-28 22:00
log does not need rotating (log has been already rotated)
considering log /var/log/nginx/error.log
Now: 2023-07-28 22:51
Last rotated at 2023-07-28 22:00
log does not need rotating (log has been already rotated)
not running postrotate script, since no logs were rotated
■ 로그 로테이션이 실행되는 시간
logrotate를 설치하는 시점에 “/etc/cron.daily/logrotate”라는 Shell 스크립트 파일도 설치된다. 이 스크립트는 단순히 logrotate를 실행할 뿐 실패하면 logger 명령을 이용하여 현재 상황을 syslog로 전달한다.
$ cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE
logrotate가 실행되는 시간은 “/etc/anacrontab”에 다음과 같이 기술되어 있다.
$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
| 구분 | 해설 |
|---|---|
| RANDOM_DELAY=45 | 0~45분 사이에서 무작위로 실행 지연 시간을 결정한다는 의미, 이 값을 0으로 설정하면 무작위 지연이 없어진다. |
| START_HOURS_RANGE=3-22 | 시작 시각의 번위는 3~22시 사이로 결정한다는 의미 |
| 1 5 cron.daily | cron.daily는 1일 1회 실행한다. 단, 5분은 반드시 지연시킨다. |
■ logrotate 동작에서의 cron과 anacron 차이
logrotate의 실행 시간은 CentOS 5까지는 /etc/crontab에 기술 되었으나 CentOS 6 이후 부터는 /etc/anacrontab 으로 변경되었다.
cron은 시스템이 켜져 있는 동안 주기적인 작업을 실행하는 방식이고, anacron은 시스템이 정지하더라도 재부팅 시점에서 예약된 작업을 실행하는 방식입니다.
매일 4시 2분에 작업을 실행한다 가정했을 때, CentOS 5에서는 서버가 4시 2분에 멈췄다 5시에 복구되어도 매일 실행할 작업이 실행되지 않지만 CentOS 6에서는 서버가 정지했더라도 서버가 복구된 시점인 5시에서 1분이 지난 5시 1분에 anacron을 가동하여 5분 지연시킨 후 매일 해야 할 작업을 실행한다. 즉, 서버 정지 시간이 경미하게 있더라도 매일 작업은 3~22시 사이면 놓치지 않고 실행한다.
▶ 반드시 정해진 시간에 서버에서 실행되기를 원하는 경우
$ cat /etc/anacrontab
...
RANDOM_DELAY=0
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
정각에 작업을 실행하고자 하는 경우에 “RANDOM_DELAY=0” 설정하면 무작위 지연이 발생하지 않으므로 위에서 본 설정에 따라 3시 6분에 실행된다.
분을 미세하게 조정하려면 “1 5 cron.daily”의 지연 시간인 5분을 변경하면 되며, cron이 작업을 매시 1분에 시작하므로 설정을 0으로 바꿔도 1분이 된다. (설정한 시간 + 1분)
anacron은 서버가 정지해 있던 경우 복구한 다음 바로 실행하려고 하는데, 이것도 작동하지 않게 하려면 “cronie-noanacron(yum -y install cronie-noanacron)”을 사용하는 편이 좋다.
댓글 남기기