Richtige Möglichkeit, Nginx-Protokolle zu drehen


12

Ich möchte eine Rotation von Nginx-Protokollen erreichen, die:

  1. würde ohne zusätzliche Software funktionieren (dh - am besten ohne "logrotate")
  2. würde gedrehte Dateien mit Namen basierend auf dem Datum erstellen

Der beste Ansatz ist der von PostgreSQL - dh in seiner Konfigurationsvariablen log_filename kann ich% Y-% m-% d im Strftime-Stil angeben und er ändert automatisch das Anmeldedatum (oder die Uhrzeit).

Ein weiterer Ansatz von Apache - das Senden von Protokollen per Pipe an das Programm rotatelogs.

Soweit ich suchen konnte - gibt es keinen solchen Ansatz. Alles, was ich tun kann, ist, logrotate mit der Option dateext zu verwenden, aber es hat seine eigenen Nachteile, und ich würde lieber etwas verwenden, das in PostgreSQL wie | rotatelogs oder log_filename funktioniert.


Dieser Blogartikel beschreibt eine mögliche Lösung für Ihr Problem. Aber ich habe eine Frage: Warum wollen Sie nicht Logrotate verwenden? Es macht die Arbeit sehr gut, es hat fast keine Abhängigkeiten und funktioniert nachweislich (wenn man so will, ist es kampferprobt). Warum sollten Sie durch die Reifen springen und eine hausgemachte Lösung verwenden, die möglicherweise minderwertig und fehleranfällig ist, wenn Sie nur logrotate verwenden könnten (was auch nützlich sein kann, um einige andere Protokolle auf diesem Computer zu drehen)?
Josefi

logrotate (mit dateext) funktioniert fast , aber es gefällt mir nicht, weil es über cron ausgeführt werden muss und dies einige Nachteile hat.

Da Nginx das Weiterleiten seiner Protokolle an andere Programme nicht unterstützt, die Protokollrotation von sich aus nicht unterstützt und Sie keinen Cron-basierten Ansatz mögen, erhalten Sie möglicherweise nicht das, was Sie wollen. Manchmal ist "fast funktioniert" so gut wie es nur geht. ;) Es sei denn, Sie möchten natürlich selbst Nginx patchen.
Josefi

Antworten:


7

Während sich die Welt darüber teilt, ob die bescheidene Named Pipe ein Freund oder ein Feind ist, ist es wahrscheinlich die einfachste Lösung für Ihr Problem. Es hat ein paar Nachteile (Sie müssen die Pipes im Voraus erstellen), aber es macht einen Cron überflüssig und Sie können den Protokollierungs-Pipefilter Ihrer Wahl verwenden.

Hier ist ein Beispiel für die Verwendung von cronolog für access.log:

  1. Wählen Sie einen Pfad für unsere Named Pipe. Ich beabsichtige, meine Logs zu behalten /var/log/nginx, also werde ich auch meine Pfeifen dort ablegen. Der Name liegt bei Ihnen; Ich hänge an .fifo, und es ist access.logso, dass meins bei sein wird /var/log/nginx/access.log.fifo.
  2. Löschen Sie die Datei, falls vorhanden.
  3. Erstellen Sie eine Named Pipe für die Protokolldatei:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Konfigurieren Sie nginx.conf, um das Protokoll auf die soeben erstellte Pipe zu richten:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Ändern Sie Ihr init.d-Skript, um den Protokollrotator zu starten, der die Pipe abhört, bevor wir den Server starten:

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

    Eine ähnliche Befehlszeile wird verwendet, rotatelogsfalls Sie dies vorziehen cronolog- Informationen zur Syntax finden Sie in den zugehörigen Dokumenten.

    Wenn Ihre Distribution eine hat start-stop-daemon, sollten Sie stattdessen diese verwenden, da sie theoretisch über das spezielle Wissen über Ihre Plattform verfügt und sich um pkillSie kümmert . Wickeln Sie einfach den Befehl in einem Skript, und übergeben Sie es als --execzu start-stop-daemonIhrer init.d/nginx.


Ich liebe Cronolog; Es ist gut zu sehen, dass mehr Leute es benutzen / empfehlen.
Natacado

1

Ich habe ein einfaches Programm, datelog, geschrieben, um allgemeine Protokolle basierend auf dem protokollierten Datum zu teilen, im Gegensatz zur aktuellen Systemzeit, wenn die Protokollzeile vom Programm gesehen wird. Dies kann oder kann nicht genau das sein, was cronolog oder ein anderer Protokollteiler bereits tut, aber es war schneller, meine eigenen zu schreiben, als herauszufinden, was andere tun.

Unter Verwendung von Jahr und Monat in der protokollierten Anforderung wird die Zeile dann in eine Datei oder Pipe geschrieben, die das aus den protokollierten Daten berechnete JJJJMM enthält. Ja, dies ist etwas spezifisch für das übliche Protokollformat. Es wird angenommen, dass das erste [das Datum begrenzt. Vorsicht vor IPv6-Adressen. :)

Für die Protokollanalyse ist es wichtig, dass jedes Protokoll wirklich nur die Anforderungen für den jeweiligen Monat enthält. Idealerweise sollte jedes Protokoll vollständig sein, um korrekte Analyseergebnisse zu erzielen. Es reicht nicht aus, den Dateinamen anhand der aktuellen Zeit im Protokollteiler zu ermitteln, da eine langsame Anforderung ab 23:59:59 dann für den falschen Monat in der Protokolldatei endet.

Ich verwende dies mit nginx über ein benanntes FIFO, das vor dem Start von nginx auf Existenz überprüft wird. Beachten Sie, dass es im Programm einen Kompromiss zwischen Fehlererkennung und gepufferter Ausgabe gibt, bei dem die Datenprotokollierung derzeit aus Leistungsgründen die gepufferte Ausgabe bevorzugt. Stellen Sie daher sicher, dass Ihr Setup wirklich funktioniert, insbesondere bei Verwendung von Shell-Pipes, damit keine Protokolldaten verloren gehen .

Quellcode: http://stuge.se/datelog.c

Bitte senden Sie mir Feedback und natürlich Patches!


1

Sie können dies mit einem einfachen Bash-Skript und Cron erreichen:

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

Weitere Informationen zum Einrichten von crontab usw. finden Sie hier: Rotieren von Nginx-Protokolldateien über Cron


0

Ich fürchte, ich verstehe Ihre Frage nicht wirklich: Da Nginx keine eingebaute Logrotation unterstützt, müssen Sie sich für so etwas entscheiden

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

Irgendwo in /etc/cron.daily (Sie müssen die oben genannten Dateinamen natürlich mit vollständigen Pfadnamen versehen) oder die Hilfsprogramme apache2 installieren, um auf rotatelogs zugreifen zu können.


Das ist das gleiche, wie ich es mit Logrotate machen könnte. Und ich will es besser.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.