Я пробовал это руководство для ротации файла журнала без внешнего программного обеспечения, но, похоже, это не работает, моя конфигурация на 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 version: nginx/1.8.0

built with OpenSSL 1.0.2a 19 Mar 2015

TLS SNI support enabled

configure arguments: --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

answer

См. Мой комментарий выше и рассуждения 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где у вас есть текущие команды ведения журнала.

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

Please note, that it’s not possible to embed variables in error_log directives, as any potential error would not be able to be logged if the file cannot be written.

Имея это в виду, невозможно автоматически преобразовать журнал ошибок в соответствии с форматом именования 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

Затем добавьте cronjob в ваш crontab, который будет вращать журнал каждую ночь в полночь:

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

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

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 не требуется.