Назад | Перейти на главную страницу

Ротация журналов на NginX в файле конфигурации

я пробовал этот учебник по ротации файла журнала без внешнего программного обеспечения, но похоже, что он не работает, моя конфигурация на server { блок:

if ($time_iso8601 ~ "^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})") {}
access_log /var/log/access-$year-$month-$day.log;
error_log /var/log/error-$year-$month-$day.log;

и созданный файл с именем:

-rw-r--r-- 1 root root    0 May 28 17:46 error-$year-$month-$day.log

моя версия NginX:

версия nginx: nginx / 1.8.0

построен с OpenSSL 1.0.2a 19 марта 2015 г.

Включена поддержка TLS SNI

настроить аргументы: --prefix = / etc / nginx --conf-path = / etc / nginx / nginx.conf --sbin-path = / usr / bin / nginx --pid-path = / run / nginx.pid - -lock-path = / run / lock / nginx.lock --user = http --group = http --http-log-path = / var / log / nginx / access.log --error-log-path = stderr --http-client-body-temp-path = / var / lib / nginx / client-body --http-proxy-temp-path = / var / lib / nginx / proxy --http-fastcgi-temp-path = / var / lib / nginx / fastcgi --http-scgi-temp-path = / var / lib / nginx / scgi --http-uwsgi-temp-path = / var / lib / nginx / uwsgi --with-imap - -with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module - with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module

Согласно этому сообщению в блоге,

Обратите внимание, что встроить переменные в error_log директивы, поскольку любая потенциальная ошибка не может быть зарегистрирована, если файл не может быть записан.

Имея это в виду, невозможно автоматическое преобразование журнала ошибок в соответствии с форматом именования. error-$year-$month-$day.log используя этот метод Nginx.


Однако настроить ротацию журнала для журнала ошибок не очень сложно. Создайте простой сценарий оболочки (bash) в /usr/local/bin/rotate_nginx_error_log.sh:

#!/bin/sh
# /usr/local/bin/rotate_nginx_error_log.sh

# Get yesterday's date as YYYY-MM-DD
YESTERDAY=$(date -d 'yesterday' '+%Y-%m-%d') 

PID_FILE=/run/nginx.pid
LOG_FILE=/var/log/error.log
OLD_FILE=/var/log/error-$YESTERDAY.log

# Rotate yesterday's log.
mv $LOG_FILE $OLD_FILE

# Tell nginx to reopen the log file.
kill -USR1 $(cat $PID_FILE)

Убедитесь, что у него есть разрешения для исполняемого файла:

chmod +x /usr/local/bin/rotate_nginx_error_log.sh

Затем добавьте задание cron в свой crontab, которое будет вращать журнал каждую ночь в полночь:

0 0 * * * /usr/local/bin/rotate_nginx_error_log.sh

См. Мой комментарий выше и рассуждения cpburnz, но если вы действительно хотите продолжить:

Вы можете написать сценарий, который записывает только команды журнала во включаемый файл с жестко заданной текущей датой. У тебя было бы это included в конфигурационный файл nginx, и ваш скрипт перезапустит или перезагрузит nginx после записи команд журнала в включаемый файл.

Что-то вроде:

#!/bin/bash

date=`date -Id`

cat > /etc/nginx/includes/log_by_date.inc <<EOF
access_log /var/log/access-${date}.log;
error_log /var/log/error-${date}.log;
EOF

/etc/init.d/nginx restart

Вы запустите это из cron, скорее всего, около полуночи.

плюс конечно вам нужно include /etc/nginx/includes/log_by_date.inc где у вас есть текущие команды ведения журнала.

Вот что у меня на сервере:

if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
    set $year $1;
    set $month $2;
    set $day $3;
}

access_log /path/to/logs/nginx-access-$year-$month.log;

Теперь иногда $time_iso8601 имеет не ожидаемый формат, и журналы записываются в файл с именем nginx-access--.log (на самом деле, $year и $month не установлены).

Поэтому я подумаю об изменении строк на что-то вроде этого:

if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
    set $year $1;
    set $month $2;
    set $day $3;

    access_log /path/to/logs/nginx-access-$year-$month.log;
}
else {
    access_log /path/to/logs/nginx-access-notime.log;
}

Однако, как сообщил @cpburnz, вы не сможете сделать это для журналов ошибок.

Следующее работает для журнала доступа с nginx 1.13.x

Мы хотели, чтобы наша конфигурация журнала доступа была в блоке http, если там не разрешено, поэтому вместо этого использовали map:

http {
    ...

    # Variable for access log filename date
    map $time_iso8601 $logdate {
        '~^(?<ymd>\d{4}-\d{2}-\d{2})'   $ymd;
        default                         'nodate';
    }

    log_format    acfmt    '$remote_addr "$request" "$query_string" "$http_referer" $request_time $status';
    access_log    'logs/access_${logdate}.log'    acfmt;

    ...
}

Ротация журналов происходит каждый день по первому запросу. В отличие от документации в другом месте, SIGUSR1 не требуется.