리눅스 환경에서 로그 파일은 계속해서 증가하므로, 로그 파일이 지나치게 커져서 원하는 정보를 찾기 어려워지는 것을 방지하기 위해 주기적으로 로그 파일을 분할해야 합니다. 여기서는 logrotate를 사용하여 로그를 분할하는 방법을 설명합니다.
(1).logrotate 설정 파일
logrotate 설정 파일은 주로 두 곳에 있습니다: /etc/logrotate.conf 및 /etc/logrotate.d/ 디렉토리의 세부 설정 파일입니다.
/etc/logrotate.conf 파일은 메인 설정 파일이며, /etc/logrotate.d/ 디렉토리의 모든 세부 설정 파일은 /etc/logrotate.conf에서 읽어와 실행됩니다. 여기서 공통 변수와 개별 변수의 개념이 적용됩니다.
logrotate의 실행은 crond 서비스에서 호출되며, 해당 스크립트는 /etc/cron.daily/logrotate로 매일 자동 실행됩니다. 스크립트의 내용은 다음과 같습니다:
[root@server ~]# cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
간단히 설명하면, /usr/sbin/logrotate 도구가 /var/lib/logrotate/logrotate.status와 /etc/logrotate.conf 두 파일을 호출합니다. 그 후 실행 결과($?로 표시, 성공 시 0, 실패 시 0이 아님)를 판단하여, 0이 아닐 경우 /usr/bin/logger 명령을 실행합니다. 마지막으로 스크립트가 종료됩니다.
예약 작업을 살펴보았으니, 이제 메인 설정 파일인 /etc/logrotate.conf(공통 변수)를 살펴보겠습니다:
[root@server ~]# grep -vE "^$|^#" /etc/logrotate.conf
weekly // 주간으로 rotate(회전, 실제로는 분할을 의미)
rotate 4 // 4개의 분할 파일을 유지하고 초과 시 삭제, 새로 생성된 로그 파일은 제외
create // 작업 후 새로운 빈 로그 파일 생성
dateext // 날짜를 분할 파일 접미사로 사용
include /etc/logrotate.d // /etc/logrotate.d 디렉토리의 모든 파일을 로드하여 실행
/var/log/wtmp { // /var/log/wtmp 파일에만 적용
monthly // 매월 실행
create 0664 root utmp // 작업 후 새로운 빈 로그 생성, 권한 0664, 소유자 root, 그룹 utmp
minsize 1M // 분할 파일이 최소 1M가 되어야 실행, 그렇지 않으면 실행 안 함
rotate 1 // 1개의 분할 파일만 유지하고 초과 시 삭제
}
/var/log/btmp { // /var/log/btmp에만 적용
missingok // 파일이 없어도 오류 무시
monthly // 매월 실행
create 0600 root utmp // 작업 후 새로운 빈 로그 생성, 권한 0600, 소유자 root, 그룹 utmp
rotate 1 // 1개의 분할 파일만 유지하고 초과 시 삭제
}
설정 파일 매개변수 설명:
missingok 로그 분할 중 오류 발생 시 무시(로그 파일이 없어도 오류 없이 계속 진행)
daily, weekly, monthly, yearly 매일, 매주, 매월, 매년 실행
create MODE OWNER GROUP 분할 후 새로운 빈 파일의 속성 지정
nocreate 새로운 로그 파일 생성하지 않음
rotate N N개의 분할 파일만 유지하고 초과 시 삭제(새로 생성된 로그 파일 제외)
dateext 현재 날짜를 접미사로 사용하는 형식(기본값은 연월일)
dateformat .%s dateext와 함께 사용, 다음 줄에 나타나며 분할된 파일명 정의, %Y, %m, %d, %s만 지원
size/minsize 지정된 크기에 도달했을 때만 분할, 기본 단위는 bytes, KB와 MB도 사용 가능
compress 분할 후 아카이브하고 gzip 형식으로 압축
nocompress 매개변수 해제
delaycompress 항상 매개변수와 함께 사용되며, logrotate가 가장 최근 아카이브를 압축하지 않도록 지시. 압축은 다음 분할 시 진행됨.
nodelaycompress 매개변수 해제
ifempty 로그가 비어 있어도 분할 실행
notifempty 로그가 비어 있으면 분할 실행하지 않음
prerotate/endscript 모든 다른 지시 전에 prerotate와 endscript 사이의 명령 실행
postrotate/endscript 모든 다른 지시 완료 후 postrotate와 endscript 사이의 명령 실행
sharescripts 모든 로그 분할 후 스크립트를 한 번만 실행, 이 매개변수가 없으면 각 로그 분할 후마다 스크립트 실행
errors ADDRESS 분할 시 오류 정보를 지정된 이메일 주소로 전송
mail ADDRESS 분할된 로그를 지정된 이메일 주소로 전송
nomail 분할된 로그를 이메일로 전송하지 않음
olddir DIRECTORY 분할된 로그 파일을 지정된 디렉토리로 이동, 현재 로그와 동일한 파일 시스템에 있어야 함
noolddir 분할된 로그 파일을 현재 디렉토리에 그대로 둠
copytruncate 여전히 열려 있는 로그 파일에 사용, 현재 로그를 백업하고 잘림; 복사 후 비우므로 일부 로그가 손실될 수 있음
nocopytruncate 로그 파일을 백업하지만 잘르지 않음
(2). 이전 분할 시간 확인
/var/lib/logrotate/logrotate.status 파일에 기본적으로 logrotate가 마지막으로 로그 파일을 분할한 시간이 기록됩니다.
[root@server logrotate]# cat /var/lib/logrotate/logrotate.status
logrotate state -- version 2
"/var/log/yum.log" 2019-1-2-11:30:2
"/var/log/cups/page_log" 2018-11-1-10:0:0
"/var/log/cups/error_log" 2018-11-1-10:0:0
"/var/log/boot.log" 2019-4-16-11:37:1
"/var/log/cups/access_log" 2019-4-15-10:18:1
"/var/log/chrony/*.log" 2018-11-1-10:0:0
"/var/log/wtmp" 2018-11-1-10:0:0
"/var/log/spooler" 2019-4-15-10:18:1
"/var/log/btmp" 2019-4-8-15:13:1
"/var/log/iscsiuio.log" 2018-11-1-10:0:0
"/var/log/maillog" 2019-4-15-10:18:1
"/var/log/libvirt/libvirtd.log" 2018-11-1-10:0:0
"/var/log/libvirt/qemu/*.log" 2018-11-1-10:0:0
"/var/log/wpa_supplicant.log" 2018-11-1-10:0:0
"/var/log/secure" 2019-4-15-10:18:1
"/var/log/numad.log" 2018-11-1-10:0:0
"/var/log/ppp/connect-errors" 2018-11-1-10:0:0
"/var/log/messages" 2019-4-15-10:18:1
"/var/account/pacct" 2018-11-1-10:0:0
"/var/log/cron" 2019-4-15-10:18:1
(3). 맞춤형 로그 분할
먼저 sshd 서비스에서 생성하는 로그를 맞춤형으로 설정하여 실험 목표로 삼겠습니다.
[root@server ~]# vim /etc/rsyslog.conf
// 파일 끝에 다음 행 추가
local0.* /var/log/sshd.log
[root@server ~]# vim /etc/ssh/sshd_config
// SyslogFacility AUTHPRIV를 다음과 같이 변경
SyslogFacility local0
[root@server ~]# touch /var/log/sshd.log
[root@server ~]# ll /var/log/sshd.log
-rw-r--r--. 1 root root 0 4월 17 13:38 /var/log/sshd.log
[root@server ~]# systemctl restart sshd
[root@server ~]# systemctl restart rsyslog.service
[root@server ~]# ll /var/log/sshd.log
-rw-r--r--. 1 root root 352 4월 17 13:38 /var/log/sshd.log
그다음 분할 세부 설정 파일을 생성하고 강제 실행합니다.
[root@server ~]# vim /etc/logrotate.d/sshd
[root@server ~]# cat /etc/logrotate.d/sshd
/var/log/sshd.log{
missingok
weekly
create 0600 root root
dateext
rotate 3
}
[root@server ~]# systemctl restart rsyslog.service
[root@server ~]# logrotate -vf /etc/logrotate.d/sshd
reading config file /etc/logrotate.d/sshd
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/sshd.log forced from command line (3 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/sshd.log
log needs rotating
rotating log /var/log/sshd.log, log->rotateCount is 3
dateext suffix '-20190417'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding old rotated logs failed
fscreate context set to unconfined_u:object_r:var_log_t:s0
renaming /var/log/sshd.log to /var/log/sshd.log-20190417
creating new /var/log/sshd.log mode = 0600 uid = 0 gid = 0
set default create context
[root@server ~]# ll /var/log/sshd*
-rw-------. 1 root root 0 4월 17 13:47 /var/log/sshd.log
-rw-r--r--. 1 root root 352 4월 17 13:38 /var/log/sshd.log-20190417
logrotate의 -d 옵션은 시뮬레이션, -f는 강제 실행, -v는 상세 과정 표시입니다.
(4). 확장 기능
또한 셸과 파이썬을 사용하여 로그를 분할할 수도 있습니다. 여기서 전문가의 글을 참고자료로 제공합니다: 운영 환경에서의 로그 분할 작업 정리 (Logrotate/Python/셸 스크립트 구현)