NGINX 로그 기본 설정 및 logrotate 설정 방법

튜토리얼 환경 : 우분투 데스크탑 16.04 LTS Xenial / NGINX 패키지 설치

NIGNX를 웹서버로 활용하기 위해서는 패키지 관리자를 통해 설치하거나, 추가 모듈이 필요할 경우 필요한 모듈을 포함해 컴파일해 설치하게 됩니다.

패키지 관리자를 통해 설치한 경우 NGINX에 대한 엑세스 및 에러 같은 기본적인 로그는 자동으로 설정이 되는데요. 기본 설정 같은 경우 NGINX에 들어오는 모든 엑세스가 로그로 남게 되어 여러 가상 호스트를 통해 도메인을 연결한 경우 로그 분석에 비효율적이고 굳이 로그를 남기지 않아도 될 부분까지 남길 수 있기 때문에 불필요하게 자원을 소모하게 되므로 별도의 설정을 거쳐 로깅(Logging)에 불필요한 자원이 낭비되지 않도록 설정하는 것이 중요합니다.

전역&가상호스트 로그 설정

http {
   ##
   # Logging Settings
   ##

   access_log /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log;
}

우선, NGINX 기본 설정 파일인 nginx.conf를 열어 보면 위와 같은 코드를 볼수 있는데, 엑세스 로그와 에러 로그가 global(전역) 설정이 되어 있습니다.

이처럼 전역 설정이 되어 있을 경우 가상 호스트에서 별도의 엑세스 로그를 설정하지 않을 경우 모든 엑세스가 access.log에 모이기 때문에 나중에 로그를 분석할 일이 생겼을 경우 번거로워지므로 이 코드를 아래와 같이 바꿔 줍니다.

access_log off;
log_not_found off;
error_log /var/log/nginx/error.log crit;

전역으로 설정되어 있는 로그를 전부 비활성화 하고 에러 로그 같은 경우 시스템에 문제가 생기는 수준의 레벨만 로깅하게 crit으로 설정합니다.

추가된 log_not_found는 파일을 찾을수 없을때 에러 로그를 하지 않겠다는 Syntax 입니다.

server {
   ...
   access_log /var/log/nginx/도메인/access.log
   ...
}

이제 가상 호스트에서 설정된 도메인에 접속할때 엑세스 로그를 별도로 지정해야 합니다. 가상 호스트 설정 부분인 server 블럭에 위처럼 access_log를 추가하면 되겠습니다.

기본 로그 파일 위치

패키지로 NGINX를 설치한 경우 로그 파일 저장 경로는 /var/log/nginx이 되며 컴파일로 설치한 경우 별도의 옵션을 지정하지 않았다면 마찬가지 경고에 로그 파일이 저장됩니다.

로그로테이트(Logrotate) 설정

NGINX를 포함한 각종 서비스들의 로그 기록을 남길때 로그로테이트를 사용하는데요. 패키지로 설치한 경우 로그로테이트 역시 자동으로 설정되며 기본값은 아래와 같습니다. 만일 컴파일로 설치해 logrotate에 등록되지 않았다면 아래의 설정을 직접 등록하면 되겠습니다.

/var/log/nginx/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}

설정 파일은 /etc/logrotate.d에 위치하고 있으며 간단하게 위 설정을 풀이하면 매일 로그 파일을 기록하며 14일치의 로그를 저장하고 오래된 순서부터 순차적으로 삭제되게 됩니다. 그리고 저장된 로그는 gzip으로 압축해 보관하게 됩니다.

access.log    access.log.2.gz  access.log.4.gz  access.log.6.gz  error.log
access.log.1  access.log.3.gz  access.log.5.gz  access.log.7.gz  error.log.1

기본 로그 설정으로 NGINX를 서비스하고 몇일이 지난 후 /var/log/nginx 디렉토리를 확인해 보면 위처럼 로그가 쌓여가는 것을 확인할 수 있는데요.

위처럼 저장될 경우 로그를 열어보지 않는 이상 어느 날짜의 로그인지 한눈에 볼수 없고 3번째 로그부터는 gzip으로 압축저장이 되기 때문에 해당 로그를 열기 위해 압축을 풀어야하는 불편함이 있습니다.

그리고 NGINX의 가상호스트에서 로그를 별도로 지정한 경우 로그로테이트에서 또한 명시해야 제대로 적용이 되기 때문에 필자는 다음과 같이 설정했습니다.

/var/log/nginx/*/*.log {
        daily
        dateext
        dateyesterday
        missingok
        rotate 30
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}

vi로 /etc/logrotate.d/nginx를 열어 나오는 기본 옵션은 놔둔 상태에서 한줄 띄우고 아래에 위와 같이 설정합니다.

위 코드를 해석하자면 NGINX 가상호스트에서 로그 경로를 /var/log/nginx/도메인으로 설정했기 때문에 여러 가상호스트를 위한 디렉토리가 존재해 모든 디렉토리에 적용될수 있게 *로 처리했습니다. 그리고 지난 로그 파일에 압축을 적용하지 않아 언제든지 열어보기 쉽게하고 최대 로그 저장기간을 30일로 설정했습니다.

그리고 access.log.2 이러한 방식의 숫자 대신 로테이트된 날짜를 파일명 뒤에 붙여 보기 편하게 설정합니다.

127.0.0.1-access.log                    extrememanual.net-access.log-20170411
127.0.0.1-access.log-20170329           extrememanual.net-access.log-20170412

위와 같이 옵션을 추가한 다음 NGINX를 운영하면 위처럼 로그가 쌓여 나중에 로그를 분석할때 직관적으로 파일을 찾을 수 있습니다. 하지만 위의 설정이 절대적인 것은 아니기 때문에 관리자가 필요한 옵션을 통해 설정하는 것이 중요합니다.

크론탭(Crontab) 설정

마지막으로 크론탭을 설정해야 합니다. 크론탭은 위에서 지정한 로그로테이트 설정을 실질적으로 실행시켜주는 스케쥴러 역할을 하는데 로그 파일 뒤의 날짜와 로그 내용이 정확하게 딱 떨어지려면 로그 스케쥴이 시작되는 시간이 00:00 정각이 되어야겠죠?

logrotate는 crontab에 하루 한번 실행되게 설정되있고 이 설정은 /etc/cron.daily/logrotate에 등록되어 있습니다. 앞서 얘기한 것처럼 정각에 로테이트 되기 위해서는 /etc/cron.daily에 등록되어 있는 설정들이 정시에 돌게 하면 되므로 /etc/crontab을 vi나 vim 편집기로 열어줍니다.

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
00 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
00 0    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
00 0    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
00 0    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

위와 같이 설정되어 있을텐데 만일 11-14줄 맨 앞에 설정되어 있는 분/시간이 00 0이 아닐 경우에는 위처럼 정각으로 변경하면 날짜가 지난 즉시 로그로테이트가 동작하고 로그 파일 역시 날짜별로 분류되어 저장됩니다.

앞서 얘기했지만 이러한 설정은 정답이 없기 때문에 관리하는 본인이 편하게 분류하는 것이 좋습니다. 일반적으로 로그를 날짜로 분류하고 필자 역시 위처럼 설정하는게 관리하기 편해서 예시로 든것이니 필요한 옵션이나 설정이 필요하다면 해당 키워드로 검색해 커스터마이징 하는 것이 좋습니다.

같은 주제의 글

댓글

이메일 주소는 공개되지 않으며 댓글에 하나 이상의 URL이 포함될 경우 관리자 승인 후 공개됩니다.

댓글은 운영 정책에 따라 관리됩니다. (링크)