Właściwy sposób na obracanie dzienników Nginx

12

Chciałbym osiągnąć rotację logów nginx, które:

  1. działałoby bez dodatkowego oprogramowania (tj. najlepiej bez „logrotate”)
  2. tworzy obrócone pliki o nazwach opartych na dacie

Najlepszym podejściem jest coś, co ma PostgreSQL - tj. W zmiennej konfiguracyjnej log_filename mogę określić styl strftime% Y-% m-% d, i automatycznie zmieni on dziennik (lub czas) zmiany.

Inne podejście z apache - wysyłanie logów za pomocą potoku do programu rotatelogs.

O ile mogłem przeszukać - takie podejście nie istnieje. Wszystko, co mogę zrobić, to użyć logrotate z opcją dateext, ale ma on swój własny zestaw wad i wolałbym użyć czegoś, co działa jak | rotatelogs lub log_filename w PostgreSQL.

Bryan
źródło
W tym artykule na blogu opisano możliwe rozwiązanie problemu. Ale mam pytanie: dlaczego nie chcesz używać logrotate? Bardzo dobrze sobie radzi, nie ma prawie żadnych zależności i udowodniono, że działa (zahartowany w boju, jeśli chcesz). Po co przeskakiwać przez obręcze i korzystać z własnego rozwiązania, które może być gorsze i podatne na błędy, jeśli można po prostu użyć logrotate (co może być również przydatne do obracania innych dzienników na tym komputerze)?
joschi
logrotate (z datownikiem) prawie działa, ale mi się nie podoba, ponieważ musi być uruchamiany przez crona, a to ma pewne wady.
Ponieważ nginx nie obsługuje pipowania swoich logów do innych programów, sam nie obsługuje rotacji logów i nie podoba ci się podejście oparte na cronie, możesz nie całkiem dostać tego, czego chcesz. Czasami „prawie działa” jest tak dobre, jak to tylko możliwe. ;) Chyba że chcesz samodzielnie załatać nginx.
joschi

Odpowiedzi:

7

Chociaż świat jest podzielony co do tego, czy skromna nazwana fajka jest przyjacielem czy wrogiem, jest to prawdopodobnie najprostsze rozwiązanie twojego problemu. Ma kilka wad (polegających na tym, że trzeba wcześniej utworzyć rury), ale eliminuje potrzebę użycia crona i pozwala na użycie wybranego filtru rur rejestrujących.

Oto przykład użycia cronologa na access.log:

  1. Wybierz ścieżkę dla naszego nazwanego potoku. Zamierzam zachować moje logi /var/log/nginx, więc tam też włożę fajki. Imię należy do ciebie; Dołączam .fifoi tak access.log, więc mój będzie /var/log/nginx/access.log.fifo.
  2. Usuń plik, jeśli istnieje.
  3. Utwórz nazwany potok dla pliku dziennika:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Skonfiguruj, nginx.confaby skierować dziennik na właśnie utworzony potok:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Zmodyfikuj skrypt init.d, aby uruchomić rejestrator dziennika nasłuchujący potoku przed uruchomieniem serwera:

    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" ) &
    

    Podobna komenda byłaby użyta, rotatelogsjeśli wolisz cronolog- zobacz ich dokumentację dotyczącą składni.

    Jeśli masz dystrakcję start-stop-daemon, powinieneś z niej skorzystać, ponieważ teoretycznie ma ona jakąkolwiek specjalną wiedzę na temat twojej platformy i się o nią troszczy pkill. Wystarczy owinąć polecenia w skrypcie, i przekazać go jako --execcelu start-stop-daemonw swoje init.d/nginx.

dsc
źródło
Kocham cronologa; dobrze jest widzieć więcej osób korzystających / polecających go.
natacado
1

Napisałem prosty program, dziennik danych, do dzielenia wspólnych dzienników na podstawie zarejestrowanej daty, w przeciwieństwie do bieżącego czasu systemowego, gdy program widzi linię dziennika. To może, ale nie musi być dokładnie to, co robi cronolog lub inny rozdzielacz logów, ale napisanie własnego było szybsze niż sprawdzenie, co robią inni.

Wykorzystując rok i miesiąc w zarejestrowanym żądaniu, wiersz jest następnie zapisywany w pliku lub potoku, który zawiera RRRRMM obliczony na podstawie zarejestrowanych danych. Tak, jest to nieco specyficzne dla wspólnego formatu dziennika. Pierwszy [zakłada się, że wyznacza datę. Uważaj na adresy IPv6. :)

W przypadku analizy dziennika ważne jest, aby każdy dziennik zawierał tylko żądania dla każdego odpowiedniego miesiąca, a każdy dziennik powinien być idealnie kompletny, aby uzyskać poprawne wyniki analizy. Nie wystarczy określić nazwę pliku na podstawie aktualnego czasu w rozdzielaczu dziennika, ponieważ wolne żądanie zaczynające się o 23:59:59 skończy w pliku dziennika dla niewłaściwego miesiąca.

Używam tego z nginx jako nazwany fifo, który sprawdza się przed uruchomieniem nginx. Zauważ, że w programie występuje kompromis między wykrywaniem błędów a buforowanym wyjściem, w którym dziennik danych obecnie preferuje buforowane wyjście ze względu na wydajność, więc upewnij się, że konfiguracja naprawdę działa, szczególnie podczas korzystania z potoków powłoki, aby nie stracić żadnych danych dziennika .

Kod źródłowy: http://stuge.se/datelog.c

Prześlij mi swoją opinię i oczywiście łatki!

ogromny
źródło
1

Możesz to osiągnąć za pomocą prostego skryptu bash i crona:

#!/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

Więcej informacji na temat konfigurowania crontab itp. Można znaleźć tutaj: Obracanie plików dziennika Nginx za pośrednictwem Crona

John Collins
źródło
0

Obawiam się, że tak naprawdę nie rozumiem twojego pytania: ponieważ nginx nie obsługuje żadnej wbudowanej logrotacji, będziesz musiał wybrać coś takiego

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

gdzieś w /etc/cron.daily (powyższe nazwy plików należy oczywiście zakwalifikować pełnymi ścieżkami) lub zainstalować narzędzia apache2, aby mieć dostęp do rotatelogów.

Stefan Förster
źródło
To samo, co mogłem zrobić z Logrotate. I chcę tego lepiej.