Я хотел бы добиться ротации логов nginx, которые:
Лучший подход - это что-то вроде PostgreSQL, то есть в его переменной конфигурации log_filename я могу указать% Y-% m-% d в стиле strftime, и он автоматически изменит изменение даты (или времени) входа в систему.
Другой подход от apache - отправка логов по конвейеру в программу rotatelogs.
Насколько мне удалось поискать - такого подхода не существует. Все, что я могу сделать, это использовать logrotate с опцией dateext, но у него есть свой набор недостатков, и я бы предпочел использовать что-то, что работает как | rotatelogs или log_filename в PostgreSQL.
Хотя мир разделен на то, является ли скромный именованный канал другом или врагом, это, вероятно, самое простое решение вашей проблемы. У него есть несколько недостатков (в том, что вам нужно создать каналы заранее), но он устраняет необходимость в cron и позволяет вам использовать канал-фильтр журналирования по вашему выбору.
Вот пример использования cronolog на access.log
:
/var/log/nginx
, так что я тоже положу туда свои трубки. Имя зависит от вас; Я добавляю .fifo
, и это access.log
, так что мой будет в /var/log/nginx/access.log.fifo
.Создайте именованный канал для файла журнала:
mkfifo /var/log/nginx/access.log.fifo
Настроить nginx.conf
чтобы навести бревно на только что сделанную вами трубу:
access_log /var/log/nginx/access.log.fifo;
Измените сценарий init.d, чтобы ротатор журналов слушал канал. перед запускаем сервер:
LOGS="/var/log/nginx"
pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
Аналогичная командная строка будет использоваться для rotatelogs
если ты предпочитаешь это cronolog
- см. их документацию по синтаксису.
Если в вашем дистрибутиве есть start-stop-daemon
, вы должны использовать это вместо этого, поскольку теоретически он имеет все специальные знания о вашей платформе, и заботится о pkill
для тебя. Просто оберните команду в сценарий и передайте ее как --exec
к start-stop-daemon
в твоем init.d/nginx
.
Вы можете добиться этого с помощью простого сценария bash и cron:
#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE
Подробнее о настройке crontab и т. Д. Можно найти здесь: Ротация файлов журналов Nginx через Cron
Я написал простую программу, datelog, для разделения общих журналов на основе зарегистрированной даты, в отличие от текущего системного времени, когда программа видит строку журнала. Это может быть, а может и не быть именно тем, что уже делает cronolog или другой разделитель журналов, но было быстрее написать свой собственный, чем узнать, что делают другие.
Используя год и месяц в зарегистрированном запросе, строка затем записывается в файл или канал, который включает YYYYMM, вычисленный на основе зарегистрированных данных. Да, это несколько специфично для общего формата журнала. Предполагается, что первый [символизирует дату. Остерегайтесь адресов IPv6. :)
Для анализа журнала важно, чтобы каждый журнал действительно содержал запросы только за каждый соответствующий месяц, и каждый журнал в идеале должен быть полным для получения правильных результатов анализа. Недостаточно определить имя файла на основе текущего времени в разделителе журнала, потому что медленный запрос, начинающийся в 23:59:59, затем попадет в файл журнала за неправильный месяц.
Я использую это с nginx в виде именованного fifo, существование которого проверяется до запуска nginx. Обратите внимание, что в программе существует компромисс между обнаружением ошибок и буферизованным выводом, где datelog в настоящее время предпочитает буферизованный вывод по соображениям производительности, поэтому убедитесь, что ваша установка действительно работает, особенно при использовании каналов оболочки, чтобы не потерять данные журнала .
Исходный код: http://stuge.se/datelog.c
Пожалуйста, не стесняйтесь присылать мне любые отзывы и, конечно же, патчи!
Боюсь, я не совсем понимаю ваш вопрос: поскольку nginx не поддерживает никакого встроенного logrotation, вам придется пойти с чем-то вроде
mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)
где-нибудь в /etc/cron.daily (вам, конечно же, необходимо указать указанные выше имена файлов полными путями) или установить утилиты apache2, чтобы иметь доступ к rotatelogs.