Записать журнал nginx access_log и error_log в STDOUT и STDERR главного процесса.

137

Есть ли способ сохранить главный журнал процесса в STDOUT STDERR вместо файла?

Кажется, что вы можете передать путь к файлу только директиве access_log:

access_log  /var/log/nginx/access.log

То же самое и с error_log:

error_log /var/log/nginx/error.log

Я понимаю, что это может просто не быть особенностью nginx, меня бы заинтересовало краткое решение, которое, например, использует хвост. Хотя предпочтительно, чтобы он исходил от главного процесса, потому что я запускаю nginx на переднем плане.

Quinn
источник
14
Используете Nginx внутри контейнера Docker? Проверить этот ответ .
czerasz
Принятый ответ (Патрика) работает для официальных образов Nginx Docker (hub.docker.com/_/nginx).
Фаршид Т.

Ответы:

198

Изменить: похоже, что nginx теперь поддерживает, error_log stderr;как указано в ответе Anon .

Вы можете отправить логи по адресу /dev/stdout. В nginx.conf:

daemon off;
error_log /dev/stdout info;

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

изменить: может потребоваться запустить ln -sf / proc / self / fd / dev / при использовании определенных контейнеров докеров, а затем использовать /dev/fd/1или/dev/fd/2

Патрик
источник
2
Когда я пытаюсь это сделать, я получаю следующую ошибку: 2014/07/29 10:19:09 [Emerg] 13742 # 0: open () "/ dev / stdout" не удалось (13: доступ запрещен)
Джон Тирсен,
1
Джон, в какой ты системе? В моей системе / dev / stdout - это доступная для чтения символическая ссылка на / dev / fd / 1, которая принадлежит моему пользователю и доступна для чтения и записи.
Патрик
1
Я вижу это сбой, ENXIOкогда stdout открыт для сокета, а не для файла. Существует билет ядра восходящего потока, указывающий, что это сделано намеренно и намеренно: bugzilla.kernel.org/show_bug.cgi?id=1360 - таким образом, хотя в некоторых случаях этого ответа достаточно, он не полностью охватывает диапазон возможных неудачи.
Чарльз Даффи
1
Потерял на это несколько часов без особого успеха. Пытался все изменить (режимы демона, пользователи, версии nginx и т. Д.). У меня это просто не работает. "" "open ()" / dev / stderr "не удалось (6: нет такого устройства или адреса)" "" (те же проблемы с stdout, но nginx должен выводить stderrсогласно документам)
Иван Клешнин,
1
Внутри докера вы можете получить отказ в разрешении, если ваш процесс не запускается в контейнере с правами root. В следующей версии будет исправление для этого.
Добс Вандермейер
54

Если вопрос связан с докером ... официальные образы докеров nginx делают это, создавая мягкие ссылки на stdout / stderr

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

ССЫЛКА: https://microbadger.com/images/nginx

Boeboe
источник
5
Этот ответ в основном правильный, но, к сожалению, не для изображений alpine (см. Github.com/nginxinc/docker-nginx/blob/master/stable/alpine/… ), только для других, таких как jessie , используется это утверждение. Если вы пользователь alpine, просто создайте свой собственный Dockerfile с помощью 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
Ответ Патрика работает для официальных образов nginx ( hub.docker.com/_/nginx ), как для debian (последняя версия ), так и для альпийских баз.
Фаршид Т.
Ваша ссылка REF, похоже, мертва.
peedee
@jonashackt Я использовал альпийские изображения и обнаружил, что они также
записаны
Щелкните версию ( hub.docker.com/_/nginx ), чтобы увидеть файл докера с вышеупомянутой строкой (где-то перед строкой 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

Не используйте: /dev/stderr это нарушит вашу настройку, если вы собираетесь использовать systemd-nspawn.

скоро
источник
5

При запуске Nginx в контейнере Docker имейте в виду, что том, смонтированный над каталогом журналов, лишает смысла создание мягкой ссылки между файлами журнала и stdout / stderr в вашем Dockerfile, как описано в ответе @Boeboe .

В этом случае вы можете либо создать программную ссылку в своей точке входа (выполняется после монтирования томов), либо вообще не использовать том (например, когда журналы уже собраны центральной системой ведения журналов).

veuncent
источник
3

В образе докера PHP-FPM я видел такой подход:

# 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
Олег Неумывакин
источник
1

Для отладки:

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

Для классической цели

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

требовать

Под кронштейном сервера в файле конфигурации

access_log /dev/stdout;
intika
источник