Avoir nginx access_log et error_log log sur STDOUT et STDERR du processus maître

137

Existe-t-il un moyen d'avoir le journal de processus principal vers STDOUT STDERR au lieu d'un fichier?

Il semble que vous ne pouvez passer un chemin de fichier qu'à la directive access_log:

access_log  /var/log/nginx/access.log

Et il en va de même pour error_log:

error_log /var/log/nginx/error.log

Je comprends que cela ne soit tout simplement pas une fonctionnalité de nginx, je serais intéressé par une solution concise qui utilise tail, par exemple. Il est cependant préférable que cela vienne du processus maître car j'exécute nginx au premier plan.

quinn
la source
14
Vous utilisez Nginx dans un conteneur Docker? Découvrez cette réponse .
czerasz
La réponse acceptée (celle de Patrick) fonctionne pour les images officielles de Nginx Docker (hub.docker.com/_/nginx).
Farshid T

Réponses:

198

Edit: il semble que nginx prend désormais en charge error_log stderr;comme mentionné dans la réponse d'Anon .

Vous pouvez envoyer les journaux à /dev/stdout. Dans nginx.conf:

daemon off;
error_log /dev/stdout info;

http {
  access_log /dev/stdout;
  ...
}

edit: peut avoir besoin d'exécuter ln -sf / proc / self / fd / dev / si vous utilisez certains conteneurs docker, puis utilisez /dev/fd/1ou/dev/fd/2

Patrick
la source
2
Lorsque j'essaye de faire cela, j'obtiens l'erreur suivante: 2014/07/29 10:19:09 [émerg] 13742 # 0: open () "/ dev / stdout" a échoué (13: Autorisation refusée)
Jon Tirsen
1
Jon, sur quel système êtes-vous? Sur mon système, / dev / stdout est un lien symbolique lisible par le monde vers / dev / fd / 1 qui est détenu et peut être lu + écrit par mon utilisateur.
Patrick
1
Je vois cet échec ENXIOlorsque stdout est ouvert sur une socket plutôt que sur un fichier. Il y a un ticket de noyau en amont indiquant que c'est délibéré et intentionnel: bugzilla.kernel.org/show_bug.cgi?id=1360 - ainsi, bien que cette réponse soit suffisante dans certains cas, elle ne couvre pas entièrement la gamme des possibles les échecs.
Charles Duffy
1
J'ai perdu quelques heures là-dessus sans aucun succès. J'ai essayé de tout changer (modes de démon, utilisateurs, versions de nginx, etc.). Cela ne fonctionne tout simplement pas pour moi. "" "open ()" / dev / stderr "a échoué (6: aucun périphérique ou adresse de ce type)" "" (mêmes problèmes avec stdout, mais nginx devrait afficher stderrselon la documentation)
Ivan Kleshnin
1
À l'intérieur d'un docker, vous pouvez obtenir l'autorisation refusée si votre processus ne s'exécute pas en tant que root dans le conteneur. Il y a un correctif à venir pour cela dans la prochaine version.
Dobes Vandermeer
54

Si la question est liée au docker ... les images officielles du docker nginx le font en créant des liens logiciels vers stdout / stderr

RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log

RÉF: https://microbadger.com/images/nginx

Boeboe
la source
5
Cette réponse est généralement correcte, mais malheureusement pas pour les images alpines (voir github.com/nginxinc/docker-nginx/blob/master/stable/alpine/… ), seulement pour les autres comme jessie utilisent cette déclaration. Si vous êtes un utilisateur alpin, créez simplement votre propre Dockerfile avec FROM nginx:alpine RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log CMD ["nginx-debug", "-g", "daemon off;"]
jonashackt
1
La réponse de Patrick fonctionne pour les images officielles nginx ( hub.docker.com/_/nginx ), à la fois pour les bases debian (dernière version) et alpines.
Farshid T
Votre lien REF semble être mort.
peedee
@jonashackt J'ai utilisé des images alpines et je l'ai trouvé également connecté à stdout
Qiulang
Cliquez sur une version ( hub.docker.com/_/nginx ) pour voir le fichier docker avec la ligne susmentionnée (quelque part avant la ligne 100).
qräbnö
24
Syntax: error_log file | stderr | syslog:server=address[,parameter=value] | memory:size [debug | info | notice | warn | error | crit | alert | emerg];
Default:    
error_log logs/error.log error;
Context:    main, http, stream, server, location

http://nginx.org/en/docs/ngx_core_module.html#error_log

Ne pas utiliser: /dev/stderr Cela interrompra votre configuration si vous utilisez systemd-nspawn.

Anon
la source
5

Lors de l'exécution de Nginx dans un conteneur Docker, sachez qu'un volume monté sur le répertoire du journal ne permet pas de créer un lien souple entre les fichiers journaux et stdout / stderr dans votre Dockerfile, comme décrit dans la réponse de @Boeboe .

Dans ce cas, vous pouvez soit créer le softlink dans votre point d'entrée (exécuté après le montage des volumes) ou ne pas utiliser du tout un volume (par exemple lorsque les journaux sont déjà collectés par un système de journalisation central).

veuncent
la source
3

Dans l'image docker de PHP-FPM, j'ai vu une telle approche:

# cat /usr/local/etc/php-fpm.d/docker.conf
[global]
error_log = /proc/self/fd/2

[www]
; if we send this to /proc/self/fd/1, it never appears
access.log = /proc/self/fd/2
Oleg Neumyvakin
la source
1

À des fins de débogage:

/usr/sbin/nginx -g "daemon off;error_log /dev/stdout debug;"

Dans un but classique

/usr/sbin/nginx -g "daemon off;error_log /dev/stdout info;"

Exiger

Sous le support de serveur sur le fichier de configuration

access_log /dev/stdout;
intika
la source