Façon appropriée de faire pivoter les journaux Nginx

12

Je voudrais obtenir une rotation des journaux nginx qui:

  1. fonctionnerait sans logiciel supplémentaire (c'est-à-dire - mieux si sans "logrotate")
  2. créerait des fichiers tournés avec des noms basés sur la date

La meilleure approche est quelque chose comme PostgreSQL - c'est-à-dire que dans sa variable de configuration log_filename, je peux spécifier le style strftime% Y-% m-% d, et cela changera automatiquement la date (ou l'heure) de connexion.

Une autre approche d'apache - l'envoi de journaux via pipe au programme rotatelogs.

Pour autant que j'ai pu effectuer des recherches, aucune approche de ce type n'existe. Tout ce que je peux faire, c'est d'utiliser logrotate avec l'option dateext, mais il a son propre ensemble d'inconvénients, et je préfère utiliser quelque chose qui fonctionne comme | rotatelogs ou log_filename dans PostgreSQL.

Bryan
la source
Cet article de blog décrit une solution possible à votre problème. Mais j'ai une question: pourquoi ne voulez-vous pas utiliser logrotate? Il fait très bien le travail, il n'a presque pas de dépendances et a fait ses preuves (endurci au combat si vous voulez). Pourquoi sauter à travers les cerceaux et utiliser une solution locale qui peut être inférieure et sujette aux erreurs, si vous pouviez simplement utiliser logrotate (qui peut également être utile pour faire tourner d'autres journaux sur cette machine)?
joschi
logrotate (avec dateext) fonctionne presque , mais je ne l'aime pas car il doit être exécuté via cron, ce qui présente certains inconvénients.
Étant donné que nginx ne prend pas en charge le transfert de ses journaux vers d'autres programmes, ne prend pas en charge la rotation des journaux par lui-même et que vous n'aimez pas une approche basée sur cron, vous n'obtiendrez peut-être pas tout à fait ce que vous voulez. Parfois, "presque fonctionne" est aussi bon que possible. ;) À moins, bien sûr, que vous ne vouliez patcher vous-même nginx.
joschi

Réponses:

7

Alors que le monde est divisé sur le fait que l'humble pipe nommée soit amie ou ennemie, c'est probablement la solution la plus simple à votre problème. Il présente quelques inconvénients (en ce sens que vous devez créer les tuyaux à l'avance), mais il élimine le besoin d'un cron et vous permet d'utiliser le filtre de tuyaux de diagraphie de votre choix.

Voici un exemple d'utilisation de cronolog sur access.log:

  1. Choisissez un chemin pour notre pipe nommée. J'ai l'intention de conserver mes journaux /var/log/nginx, je vais donc y mettre mes tuyaux également. Le nom vous appartient; J'ajoute .fifo, et c'est access.log, donc le mien sera à /var/log/nginx/access.log.fifo.
  2. Supprimez le fichier s'il existe.
  3. Créez un canal nommé pour le fichier journal:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Configurez nginx.confpour pointer le journal vers le canal que vous venez de créer:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Modifiez votre script init.d pour démarrer le rotateur de journaux en écoutant le canal avant de démarrer le serveur:

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

    Une ligne de commande similaire serait utilisée rotatelogssi vous le préférez cronolog- voir leurs documents pour la syntaxe.

    Si votre distrobution en a un start-stop-daemon, vous devriez l'utiliser à la place, car il a théoriquement tout savoir spécial sur votre plate-forme, et prendre soin de pkillvous. Enroulez simplement la commande dans un script, et le transmettre comme --execà start-stop-daemonvotre init.d/nginx.

dsc
la source
J'aime cronolog; il est bon de voir plus de gens l'utiliser / le recommander.
natacado
1

J'ai écrit un programme simple, datelog, pour diviser les journaux communs en fonction de la date enregistrée, par opposition à l'heure actuelle du système lorsque la ligne de journal est vue par le programme. Cela peut ou non être exactement ce que fait déjà Cronolog ou un autre séparateur de journaux, mais il a été plus rapide d'écrire le mien que de découvrir ce que font les autres.

En utilisant l'année et le mois dans la demande enregistrée, la ligne est ensuite écrite dans un fichier ou un canal qui inclut le YYYYMM calculé à partir des données enregistrées. Oui, c'est quelque peu spécifique pour le format de journal commun. Le premier [est censé délimiter la date. Méfiez-vous des adresses IPv6. :)

Pour l'analyse des journaux, il est important que chaque journal ne contienne vraiment que les demandes pour chaque mois respectif, et chaque journal devrait idéalement être complet pour des résultats d'analyse corrects. Il ne suffit pas de déterminer le nom de fichier en fonction de l'heure actuelle dans le séparateur de journaux, car une demande lente commençant à 23:59:59 se retrouvera ensuite dans le fichier journal pour le mauvais mois.

J'utilise ceci avec nginx au moyen d'un fifo nommé qui est vérifié pour exister avant le démarrage de nginx. Notez qu'il existe un compromis dans le programme entre la détection d'erreurs et la sortie tamponnée, où le journal de données préfère actuellement la sortie tamponnée pour des raisons de performances, alors assurez-vous que votre configuration fonctionne vraiment, en particulier lors de l'utilisation de tubes shell, afin de ne pas perdre de données de journal .

Code source: http://stuge.se/datelog.c

N'hésitez pas à m'envoyer vos commentaires et bien sûr les correctifs!

énorme
la source
1

Vous pouvez y parvenir en utilisant un simple script bash et 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

Plus de détails sur la configuration de crontab, etc. trouvés ici: Rotation des fichiers journaux Nginx via Cron

John Collins
la source
0

Je crains de ne pas vraiment comprendre votre question: comme nginx ne prend en charge aucune rotation de log intégrée, vous devrez choisir quelque chose comme

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

quelque part dans /etc/cron.daily (vous devez qualifier les noms de fichiers ci-dessus avec des chemins d'accès complets, bien sûr) ou installer les utilitaires apache2 pour avoir accès aux rotatelogs.

Stefan Förster
la source
C'est la même chose que je pourrais faire avec logrotate. Et je le veux mieux.