Thank you for reading this post, don't forget to subscribe!
Docker поддерживает более десятка различных механизмов логирования, которые позволяют получать информацию от запущенных контейнеров и сервисов. Эти механизмы называются logging drivers, ознакомиться с их полным списком можно здесь. Из данного списка нас больше всего интересует драйвер под названием gelf
- остановимся на нем подробнее.
GELF - сокращение от Graylog Extended Log Format - специального формата логов, разработанного для Graylog. Этот формат получил широкое распространение и сейчас внедрен в множество других систем сбора, хранения и обработки логов (самые известные - Logstash и Fluentd).
Согласно стандарту GELF, в каждом лог-сообщении существует следующий набор полей:
- версия;
- хост (откуда пришло сообщение);
- время (timestamp);
- сокращенный и полный вариант сообщения;
- другие поля, настроенные самостоятельно.
Иначе говоря, строка из лога:
1 2 |
127.0.0.1 - frank [10/Oct/2010:11:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 |
В GELF-формате может выглядеть, например, как структурированный json-объект (что в свою очередь значительно облегчает хранение и обработку логов):
1 2 3 4 5 6 7 8 9 10 11 |
{ <span class="hljs-attr">"client"</span>: <span class="hljs-string">"127.0.0.1"</span>, <span class="hljs-attr">"user"</span>: <span class="hljs-string">"frank"</span>, <span class="hljs-attr">"timestamp"</span>: <span class="hljs-string">"2010-10-10 11:55:36 -0700"</span>, <span class="hljs-attr">"method"</span>: <span class="hljs-string">"GET"</span>, <span class="hljs-attr">"uri"</span>: <span class="hljs-string">"/apache_pb.gif"</span>, <span class="hljs-attr">"protocol"</span>: <span class="hljs-string">"HTTP/1.0"</span>, <span class="hljs-attr">"status"</span>: <span class="hljs-number">200</span>, <span class="hljs-attr">"size"</span>: <span class="hljs-number">2326</span> } |
Для использования gelf
как драйвера по умолчанию в системе (параметр будет применен ко всем docker-контейнерам на этом хосте) необходимо в конфигурационном файле /etc/docker/daemon.json
(в Windows это C:\ProgramData\docker\config\daemon.json
) добавить следующие строки:
1 2 3 4 5 6 7 |
{ <span class="hljs-attr">"log-driver"</span>: <span class="hljs-string">"gelf"</span>, <span class="hljs-attr">"log-opts"</span>: { <span class="hljs-attr">"gelf-address"</span>: <span class="hljs-string">"udp://1.2.3.4:12201"</span> } } |
Примечание. Вместо 1.2.3.4 конечно же нужно вставить реальный адрес вашего сервера Graylog.
И перезапустить docker для применения изменений:
1 2 |
service docker restart |
Применить драйвер gelf
только для одного конкретного контейнера при его запуске можно так:
1 2 3 4 |
docker run \ --log-driver gelf –-log-opt gelf-address=udp://1.2.3.4:12201 \ alpine <span class="hljs-built_in">echo</span> hello world |
При выполнении данной команды произойдет следующее:
- Docker Engine скачает образ alpine из реджистри (если его нет локально);
- Docker Engine создаст и запустит контейнер из образа alpine;
- в запущенном контейнере выполнится команда
echo
с аргументомhello world
; - процесс внутри контейнера напишет
hello world
в stdout; - сообщение
hello world
будет перехвачено Docker Engine и отправлено драйверу логирования (logging driver); gelf
драйвер переведет сообщение в GELF-формат (кроме строкиhello world
добавит недостающие поляhost
,timestamp
и набор информации о контейнере - его ID и имя, имя и ID образа с которого запускался контейнер, переменные окружения и т.д.);- сообщение в GELF-формате будет отправлено по протоколу UDP на ip-адрес 1.2.3.4 порт 12201;
- скорее всего (это же UDP) сообщение будет доставлено на сервер Graylog2, где с ним можно будет работать.
Если вы описываете несколько контейнеров в файле docker-compose.yml
, то настройка драйвера логирования для определенного контейнера будет выглядеть так:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... ### Sphinxsearch Container ################################## sphinxsearch: container_name: sphinxsearch image: sphinx:latest volumes: - ./sphinx/sphinx.conf:/etc/sphinxsearch/sphinx.conf - sphinx:/var/lib/sphinxsearch/data logging: driver: gelf options: gelf-address: "udp://${GRAYLOG_ADDR:-graylog.lc}:12201" tag: "sphinxsearch" ... |
[/codesyntax]
Для тех, кому важно подтверждение доставки (TCP) логов от docker-контейнеров в централизованную систему хранения у меня плохие новости:
Unfortunately, the GELF logging driver in Docker only supports UDP.
Однако из других приложений сделать это можно легко и непринужденно. Протестировать отправку логов в Graylog2 из консоли можно так:
1 2 |
<span class="hljs-built_in">echo</span> <span class="hljs-_">-e</span> <span class="hljs-string">'{"version": "1.1","host":"example.org","short_message":"A short message that helps you identify what is going on","full_message":"Backtrace here\n\nmore stuff","level":1,"_user_id":9001,"_some_info":"foo","_some_env_var":"bar"}\0'</span> | nc -w 1 graylog.lc 12202 |
Подробнее о всех доступных опциях драйвера логирования gelf
можно почитать здесь.