비정기적으로 들고 오는 일 관련 이야기.
회사에서 대외(B2B) 서비스를 몇개(?) 담당하게 되었는데, 인수인계받은 시점에선 애플리케이션 로그는 매일 순환이 되는데 WAS 로그는 그렇지가 않았습니다.
그래서 웹서버나 WAS 로그를 뒤져야 할 때에는 항상, 설치 초기부터의 기록이 남아있는 로그파일에서 grep을 걸어 무거운 시간을 보내곤 했습니다.
그래서 어느순간부터 '하루치 로그 정도는 PC로 옮겨서 다룰 수 있을 정도' 로 남기고 싶었고, '잔여 로그파일 갯수를 관리해주는' 기능을 사용하고 싶었습니다.
다른 방법을 쓰려고 했는데, 결국 돌고 돌다 보니 logrotate 를 연구하게 됐네요.
다만, 약간의 문제가 있었습니다.
개발과 운영서버는 CentOS 6.6을 쓰고 있는데, 이쪽 yum 레포지토리에는 logrotate 3.7.8, 즉 구버전이 최신버전으로 올라와 있더군요.
그리고 로그 순환시 파일명에 이전 날짜를 넣을 수 있는 옵션(dateyesterday)은 3.8.0 이상 버전부터 제공되는 상황.
담당 시스템 엔지니어분께 이야기해도 시큰둥하셔서, 허락을 받고 직접 업그레이드 버전을 적용하기 위한 약간의 연구(?)를 진행하게 되었습니다.
그리고 이 글은 그 결과물이라고 생각하시면 되겠네요.
서버에서 테스트한 logrotate config 파일 정도를 공유하려고 합니다.
- 목 차 --
누르시면 바로 이동합니다.
1. 소스 컴파일 및 적용
2. 사용중인 config
1. 소스 컴파일 및 적용
리눅스에 익숙한 분들은 아시겠습니다만, 소스를 직접 컴파일해야 하는건 꽤 흔한 일입니다.
덕분에 README 에 문서화도 잘 되어 있고, 다행히 제 환경에서 컴파일도 문제없이 진행되어 비교적 큰 어려움 없이 적용을 할 수 있었습니다.
그리고 운영서버에는 가급적 추가 패키지를 설치하지 않고 진행하고 싶어서, 개발서버에 컴파일 환경을 만들고 여기서 컴파일과 테스트를 진행했습니다.
컴파일과 테스트를 마친 logrotate만 따로 옮겨서 설정을 살짝 바꿔 적용했구요. 결론부터 말하자면 이 부분도 잘 됐습니다.
사실상 README 따라하기 정도가 되긴 하지만, 궁금하면 쭉 훑어봐주시길.
우선 logrotate 의 공식 깃헙 페이지로 갑니다.
https://github.com/logrotate/logrotate
이 페이지(혹은 README)에서 Compiling 항목을 보시면, 리눅스 배포판별로 실행해야 할 명령어가 정리되어 있습니다.
제 경우는 개발/운영서버 모두 CentOS 6.6을 사용하고 있기에 yum 명령어로 구성요소를 점검한 뒤 컴파일을 진행했습니다.
구성요소 점검이 잘 되었다면 다운로드한 xz 확장자 압축파일을 푸는 데에도 문제가 없으시겠지요.
어차피 새로 프로그램을 만드는 단계니까 편한 위치에 소스를 풀어 위치시키시면 됩니다.
위 링크 안 설명대로 컴파일이 잘 진행되면, C프로그램 하나가 컴파일되어 나올겁니다.
이 프로그램은 단독으로 실행이 가능해서, 아래와 같이 소스와 다른 경로에 별도로 빼 두셔도 권한만 있다면 잘 작동합니다.
이런식으로 말이죠.
아무튼 권한을 주고 실행해보니 별 문제는 없는것 같습니다.
흘러가는 이야기지만, 제 경우는 접속한 관리계정이 root가 아니라서 sudo를 썼습니다. 참고하시고..
여기서 원래 있던 logrotate (/usr/sbin/logrotate) 를 남길지 어떨지 결정할 수 있는데, 제 경우는 시스템 경로에 있는 logrotate는 그대로 두기로 했습니다.
저 프로그램은 yum 레포지토리에서 설치하여 3.7.8이 설치되어 있는데, 제가 그냥 덮어씌우면 설치된 yum 레포지토리상 버전과 일치하지 않게 되어버리기도 하구요.
결정적으로는 '가능하면 시스템 파일을 건드리고 싶지 않아서' 였지만..
만약 개발서버와 같은 비교적 가벼운 기능을 하는 서버이거나, 혼자 가지고 노는 서버라면 그냥 덮어씌우고 쓰시는게 편합니다.
다만 이 경우는 덮어씌우기 전에 이전 파일의 소유자와 그룹, 권한은 꼭 확인해두시구요.
제 경우는 root:root, 655 로 되어있더군요.
여기에, logrotate 작동방식까지 직접 정하실 수 있습니다.
무슨 이야기인가 하면, logrotate는 기본적으로 cron.daily에 등록되어 있습니다.
그리고 crontab에 '(logrotate 절대경로) --force (config 절대경로)' 식으로 개별 설정파일을 등록해 실행하실수도 있죠.
전자의 경우는 자정이 되자 마자 순환시키기는 어려운 단점이 있습니다.
생성되는 로그의 용량 증가속도가 빠르다면 순환 단위를 좁혀야 하는데 그러기에도 한계가 있구요.
다만 제 경우는 crontab에 등록할 경우 관리포인트가 늘어난다는 점이 부담으로 다가왔습니다.
아마 서버 담당 시스템 엔지니어분께 인수인계할때도 부담으로 다가오겠죠.
cron.daily의 경우 OS 설치시 기본값으로 등록되어 있으니까요.
참고로 /etc/anacrontab 에 있는 파일을 열어보시면, cron의 daily, weekly, monthly 작업을 몇시부터 몇시 사이에, 몇분 정도의 지연을 감수할지 설정할 수가 있습니다.
손대신 적이 없다면 daily 기준 새벽 3시부터 5분의 지연을 감수하도록 설정되어 있을텐데,
저는 로그를 최대한 0시 가까이에서 끊고 싶어서 자정부터 3분 지연을 감수하도록 설정을 변경했습니다.
물론 이래도 선행 작업에 따라 최대 30분까지 뒤에 실행되더군요; 이래서 crontab에 등록하시나 봅니다.
여담이지만, 컴파일한 logrotate를 개발서버에서 운영서버로 옮기니 실행이 되지 않았습니다.
처음에는 종속성이 있는 추가 패키지가 필요한줄 알았는데, 다른 서버에서 테스트하다 보니 단순 권한 문제더군요.
아래 명령어를 적당히 사용하여 해결하였습니다. 참고하시길.
2. 사용중인 config
그리고 여기서는 며칠 고민하면서 최종적으로 서버에 적용한 config 내용을 공유하겠습니다.
설정 자체는 Apache나 Tomcat 사이에도, Tomcat 안에서도 배포된 서비스에 따라서(생성되는 로그량)까지 조금씩 다르게 적용하고 있긴 합니다만,
대략의 로그파일 내용으로 큰 틀의 세부설정을 조정한다는 개념이라 큰 틀에선 이 내용이 됩니다.
혹시나 해서 말씀드리지만, 이 설정을 기반으로 적용하시더라도 반드시 디버그는 해보시기 바랍니다.
logrotate --debug (설정파일명) 옵션을 사용하여 실행하면 logrotate가 실제 로그파일과 주변 파일들을 읽어서, 어떻게 작동할지 텍스트로 표시해줍니다.
현재 사용중이신 logrotate 버전에서 지원하지 않는 옵션 같은게 있거나 하면 오류도 표시해주구요.
애용하시길.
그리고 저처럼 logrotate 를 cron.daily 를 통해 실행하시는 경우, /etc/lorotate.conf 파일에 기록된 weekly 등의 몇몇 설정이 상속되어 적용됩니다.
이걸 원치 않으실 경우, /etc/logrotate.d 하위에 위치시키실 config 파일을 최대한 자세하게 기록하실 필요가 있습니다.
예를 들어, 순환주기에 대한 옵션이 없으면 logrotate.conf 에 설정된 weekly 옵션이 적용됩니다.
monthly 나 daily 가 있다면 weekly 대신 이 옵션이 우선되어 작동합니다.
그러니 현재 서버의 /etc/lorotate.conf 를 한번 열어보고 config 정리작업에 돌입하시는 것도 좋겠네요.
conf 파일에 있는 설정이 있다면 중복 기재할 필요가 없겠죠.
마지막으로 cron.daily 실행 기준으로는 /etc/logrotate.d 아래에 있는 모든 설정파일을 순서대로 읽어서 로그 순환작업을 실행합니다.
logrotate --force 등 수동으로 crontab에 등록하여 실행하시는 분들은 적당한 곳에 위치시키면 되겠구요.
드디어 제가 만든 설정을 정리합니다.
제 logrotate 설정은 매일 자정 넘어서 작동하는 cron.daily 특성을 고려한 옵션도 있습니다.
대표적으로 dateyesterday.
이를 감안하시고, 추가적인 logrotate config 파일의 설정 및 기타 옵션은 이 페이지를 참고하시면 됩니다.
각 옵션에 대해 부연하자면,
daily |
매일 rotate 작업 실행 |
dateext |
기본값으론 로그 끝에 1, 2, 3 ... 식으로 숫자가 붙으나, logrotate 실행날짜를 파일 끝에 붙힌다 |
dateyesterday |
dateext 옵션이 있을 때, 파일 끝에 붙히는 날짜를 logrotate 실행날짜가 아니라 전날짜로 한다 |
dateformat .%Y-%m-%d |
dateext 옵션 사용시, 포멧이 없을 경우 파일 끝에 -20190824 와 같이 날짜가 붙으나, 이 옵션으로 파일 끝에 붙히는 날짜 포멧을 줄 수 있다. 이 옵션은 (로그파일).log.2019-08-24 가 됨. |
rotate 31 |
파일을 31개 유지하겠다는 의미. 32번째 파일부터 삭제된다 |
size 5M | 시간 조건(daily, weekly ...)에 관계없이, 5MB를 넘으면 순환시킨다 |
maxsize 10M | 시간 조건(daily, weekly ...) 이전이라도 10MB를 넘으면 순환시킨다 (예- weekly로 설정되어 있을 경우, 일주일이 지나지 않았더라도 10MB를 넘으면 순환된다) |
missingok |
로그파일이 없어도 에러메시지 없이 다음 config 설정으로 넘어가 rotate 작업을 계속한다 |
notifempty |
로그파일이 비어있다면(용량 0) rotate 하지 않는다 |
create 644 |
생성되는 파일의 접근권한을 644로 한다 |
copytruncate |
rotate한 뒤, 기존 파일을 0으로 만들어 새로 기록되도록 한다 |
위 옵션 중에서 개인적으로 중요했던건 dateyesterday 옵션이었습니다.
자정이 조금 넘어서 cron.daily 가 실행되기 때문에, 대부분 이전 날짜의 작업내역이 있는 파일 끝에 실행 당일(다음날) 날짜가 붙으니 혼란스럽더군요.
그렇다고 cron.daily 작동시간을 조정하기에는 다른 cron 작업들이 있어서 무리였고..
기왕 구버전 써서 찝찝하던거, 결국 이렇게 컴파일까지 해가면서 최신에 가까운 버전을 적용하게 되어서 개운하게 생각합니다.
마지막으로, 위 내용을 참고하여 config 작성시에는 서버 안에서 작성하시길 권합니다.
윈도우에서 작성하여 리눅스로 넘기실 경우, 개행문자의 차이 등으로 인식이 제대로 되지 않을 수 있습니다.
물론 notepad++ 과 같은 에디터 툴을 쓰시는 방법도 있지만요.
다 작성하시고 나서 --debug 옵션으로 디버그 하는것도 잊지 마시기 바랍니다.
이번 글은 여기까지.
대부분은 2번을 참고하시게 되겠습니다만, 저와 비슷한 환경에 계시는 분들에게는 도움이 되셨으면 좋겠습니다.
그럼 적당히 다음 글도 정리해서 오겠습니다.
최대한 빨리 다시 오겠습니다.