Правильний спосіб обертання журналів Nginx


12

Я хотів би досягти обертання журналів nginx, які:

  1. працював би без додаткового програмного забезпечення (тобто - найкраще, якщо без "логротету")
  2. створили б обертові файли з іменами на основі дати

Найкращий підхід - це щось на кшталт PostgreSQL - тобто в його змінної config_ logname можна вказати стиль стропінгу% Y-% m-% d, і він автоматично змінить журнал про дату (або час) зміни.

Ще один підхід від apache - відправка журналів по трубі до програми rotatelogs.

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


Ця стаття в блозі описує можливе рішення вашої проблеми. Але у мене виникає питання: чому ви не хочете використовувати логротат? Він виконує цю роботу дуже добре, майже не має залежностей і, як доведеться, працює (якщо ви хочете). Навіщо стрибати через обручі і використовувати доморощене рішення, яке може бути неповноцінним і схильним до помилок, якщо ви просто можете використовувати логротат (що також може бути корисним для обертання деяких інших журналів на цій машині)?
joschi

logrotate (з dateext) майже працює, але мені це не подобається, оскільки його потрібно запускати через cron, і це має деякі недоліки.

Оскільки nginx не підтримує передачу своїх журналів до інших програм, не підтримує обертання журналу самостійно і вам не подобається підхід на основі кронів, ви можете не зовсім отримати те, що вам потрібно. Іноді "майже працює" так добре, як і виходить. ;) Якщо, звичайно, ви не хочете самостійно проклеїти nginx.
joschi

Відповіді:


7

Хоча світ розділений на те, чи покірна названа труба є другом чи ворогом, це, мабуть, найпростіше рішення вашої проблеми. У нього є кілька недоліків (в тому, що вам потрібно створити труби заздалегідь), але це позбавляє від потреби в кроні і дозволяє використовувати трубопровідний фільтр для вашого вибору.

Ось приклад використання кронолу на 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

Я написав просту програму, даталог, щоб розділити загальні журнали на основі зареєстрованої дати, на відміну від поточного системного часу, коли програма журналу бачить лінію журналу. Це може бути, а може і не бути саме тим, що кронолог чи інший роздільник журналів вже робить, але було швидше написати моє власне, ніж з'ясувати, що роблять інші.

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

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

Я використовую це з nginx за допомогою іменного fifo, який перевіряється на існування до запуску nginx. Зауважте, що в програмі є компроміс між виявленням помилок та буферизованим виводом, де datelog в даний час віддає перевагу буферизованому виводу з міркувань продуктивності, тому переконайтеся, що ваша настройка дійсно працює, особливо при використанні оболонок, щоб не втратити жодних даних журналу .

Вихідний код: http://stuge.se/datelog.c

Будь ласка, не соромтеся надсилати мені будь-які відгуки та, звичайно, патчі!


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 не підтримує вбудовану логротацію, вам доведеться погодитися з чимось на зразок

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

десь у /etc/cron.daily (потрібно, звичайно, кваліфікувати назви файлів з повними іменами шляхів) або встановити утиліти apache2, щоб мати доступ до ротаційних журналів.


Це те саме, що я міг зробити з логротатом. І я хочу цього краще.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.