Правильний спосіб обертання журналів 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.