Запись логов Apache2 в stdout / stderr?


29

Я запускаю Apache2 в Docker-контейнере и хочу ничего не записывать на диск, записывать логи в stdout и stderr. Я видел несколько разных способов сделать это ( Supervisord и stdout / stderr , журнал доступа Apache к stdout ), но это похоже на хаки. Нет ли способа сделать это по умолчанию?

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


Разве вы не хотите, чтобы эти журналы были легко доступны для устранения неполадок / отладки? Почему бы просто не записать их на (r) сервер системного журнала?
HTTP500

@ HTTP500 - они захвачены снаружи контейнера докера.
Мэтт

Если вы используете: FROM php: 5.6-apache, это уже включает журналы для stdout и stderr.
Martlark

Ответы:



25

Как насчет размещения этого в вашем Dockerfile после установки пакета apache2?

RUN ln -sf /proc/self/fd/1 /var/log/apache2/access.log && \
    ln -sf /proc/self/fd/1 /var/log/apache2/error.log

Предполагая, что это путь к журналам. Это для Ubuntu 14.04, а также работает для Ubuntu 16.04.

Примечание: если вы уверены, что символические ссылки есть /dev/stdoutили /proc/stderrесть, то вы также можете использовать их. Я предпочитаю путь к реальному файлу, поскольку он гарантированно присутствует.


прекрасно работает также с Ubuntu 16.04 :)
OkieOth

1
Блин, это гениальный взлом! Apache пытается открыть обычный файл, но перенаправляется через символическую ссылку на свой стандартный вывод с собственной точки зрения.
joonas.fi

1
Просто хочу сказать спасибо ... официальный контейнер докера apache httpd 2.4 не может записывать логи после включения ssl. Добавление этих строк + ssl_request_log в файл Docker, который извлекает данные из httpd2.4, сработало.
j.con

3
Вы можете сократить / proc / self / fd / 1 как / dev / stdout. Они точно такие же.
Чак Адамс

@ChuckAdams - они являются мягкой ссылкой и обычно существуют, но не дают никаких гарантий при построении изображений, которые они присутствуют. Особенно вырубаются микро изображения. Принимая во внимание, что ядро ​​всегда будет экспортировать / proc / self / fd / 1 & 2.
Matt

1

Не конкретно ответ на вопрос, но, возможно, лучшим способом, в зависимости от вашего сценария, было бы вообще не входить в stdout / stderr. Просто передайте логи cat в формате JSON. Это избавило бы от необходимости различать потоки, поскольку у json могли быть данные, необходимые для их различения. например, что-то вроде следующего. Это может тогда быть намного легче поглощено чем-то вроде graylog

GlobalLog "| cat - " gelf
ErrorLog "| cat - " 

LogFormat "{ \"apache_log\": \"ACCESS\", \"app_name\": \"apache\",  \"Connection\": \"%{X-Forwarded-Proto}i:%{X-Forwarded-Port}i \", \"X-Forwarded-For\": \"%{X-Forwarded-For}i\",  \"version\": \"1.1\", \"vhost\": \"%V\", \"short_message\": \"%r\", \"timestamp\": %{%s}t, \"level\": 6, \"user_agent\": \"%{User-Agent}i\", \"source_ip\": \"%a\", \"duration_usec\": %D, \"duration_sec\": %T, \"request_size_byte\": %O, \"http_status\": %s, \"http_request_path\": \"%U\", \"http_request\": \"%U%q\", \"http_method\": \"%m\", \"http_referer\": \"%{Referer}i\", \"X-Powered-By\": \"%{X-Powered-By}i\" }" gelf

ErrorLogFormat "{ \"app_name\": \"apache\",  \"apache_log\": \"ERROR\", \"time\":\"%{%Y-%m-%d}tT%{%T}t.%{msec_frac}tZ\", \"function\" : \"[%-m:%l]\" , \"process\" : \" [pid %P:tid %T] \" , \"message\" : \"%M\" ,\ \"referer\"\ : \" %{Referer}i \" }"

Существует также модуль регистрации GELF, так что вы можете транслировать напрямую с Apache на сервер типа Graylog, если вы хотите

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.