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

Правильный способ ротации журналов Nginx

Я хотел бы добиться ротации логов nginx, которые:

  1. будет работать без какого-либо дополнительного программного обеспечения (т.е. лучше всего без "logrotate")
  2. будет создавать повернутые файлы с именами на основе даты

Лучший подход - это что-то вроде PostgreSQL, то есть в его переменной конфигурации log_filename я могу указать% Y-% m-% d в стиле strftime, и он автоматически изменит изменение даты (или времени) входа в систему.

Другой подход от apache - отправка логов по конвейеру в программу rotatelogs.

Насколько мне удалось поискать - такого подхода не существует. Все, что я могу сделать, это использовать logrotate с опцией dateext, но у него есть свой набор недостатков, и я бы предпочел использовать что-то, что работает как | rotatelogs или log_filename в PostgreSQL.

Хотя мир разделен на то, является ли скромный именованный канал другом или врагом, это, вероятно, самое простое решение вашей проблемы. У него есть несколько недостатков (в том, что вам нужно создать каналы заранее), но он устраняет необходимость в cron и позволяет вам использовать канал-фильтр журналирования по вашему выбору.

Вот пример использования cronolog на access.log:

  1. Выберите путь для нашего именованного канала. Я намерен сохранить свои журналы в /var/log/nginx, так что я тоже положу туда свои трубки. Имя зависит от вас; Я добавляю .fifo, и это access.log, так что мой будет в /var/log/nginx/access.log.fifo.
  2. Удалите файл, если он существует.
  3. Создайте именованный канал для файла журнала:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Настроить nginx.conf чтобы навести бревно на только что сделанную вами трубу:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Измените сценарий 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.