Правильный способ вращения логов Nginx

12

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

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

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

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

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

Bryan
источник
Эта статья блога описывает возможное решение вашей проблемы. Но у меня есть вопрос: почему вы не хотите использовать logrotate? Он отлично справляется со своей работой, у него почти нет зависимостей и доказано, что он работает (закаленный в боях, если хотите). Зачем прыгать через обручи и использовать доморощенное решение, которое может быть неполноценным и подверженным ошибкам, если вы просто можете использовать logrotate (что также может быть полезно для поворота некоторых других журналов на этом компьютере)?
Йоси
logrotate (с dateext) почти работает, но мне он не нравится, потому что он должен быть запущен через cron, и это имеет некоторые недостатки.
Поскольку nginx не поддерживает передачу своих журналов другим программам, не поддерживает ротацию журналов самостоятельно и вам не нравится подход на основе cron, вы можете не совсем получить то, что хотите. Иногда «почти работает» так же хорошо, как и получается. ;) Если, конечно, вы не хотите патчить nginx самостоятельно.
Йоси

Ответы:

7

Хотя мир разделен на то, является ли скромная именованная труба другом или врагом, это, вероятно, самое простое решение вашей проблемы. У него есть несколько недостатков (в том смысле, что вам нужно создавать каналы заранее), но он устраняет необходимость в 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.

ЦФК
источник
Я люблю хронолога; приятно видеть больше людей, которые используют / рекомендуют его.
natacado
1

Я написал простую программу datelog для разделения общих журналов на основе зарегистрированной даты, в отличие от текущего системного времени, когда программа просматривает строку журнала. Это может или не может быть именно тем, что cronolog или другой сплиттер журналов уже делают, но быстрее написать свой, чем узнать, что делают другие.

Используя год и месяц в зарегистрированном запросе, строка затем записывается в файл или канал, который включает в себя YYYYMM, вычисленный из зарегистрированных данных. Да, это несколько специфично для общего формата журнала. Первая [предполагается, что она разделяет дату. Остерегайтесь IPv6-адресов. :)

Для анализа журнала важно, чтобы каждый журнал действительно содержал только запросы на каждый соответствующий месяц, и каждый журнал в идеале должен быть полным для правильных результатов анализа. Недостаточно определить имя файла на основе текущего времени в разделителе журнала, потому что медленный запрос, начинающийся в 23:59:59, в итоге окажется в файле журнала за неправильный месяц.

Я использую это с nginx посредством именованного fifo, которое проверяется на существование до запуска nginx. Обратите внимание, что в программе есть компромисс между обнаружением ошибок и буферизованным выводом, где datelog в настоящее время предпочитает буферизованный вывод из соображений производительности, поэтому, пожалуйста, убедитесь, что ваша установка действительно работает, особенно при использовании оболочек, чтобы не потерять какие-либо данные журнала ,

Исходный код: http://stuge.se/datelog.c

Пожалуйста, не стесняйтесь присылать мне любые отзывы и, конечно же, патчи!

stuge
источник
1

Вы можете добиться этого, используя простой 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.

Джон Коллинз
источник
0

Боюсь, я не совсем понимаю ваш вопрос: так как nginx не поддерживает встроенную logrotation, вам придется пойти с чем-то вроде

mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)

где-нибудь в /etc/cron.daily (вам, конечно, нужно указать имена файлов с полными путями) или установить утилиты apache2 для доступа к rotatelogs.

Стефан Фёрстер
источник
Это то же самое, что я мог сделать с logrotate. И я хочу это лучше.