Docker: перенаправление логов в Graylog2

Mar 1, 2018 08:53 · 525 words · 3 minute read docker graylog2

Мы уже упоминали о Graylog2 - централизованном хранилище логов и рассматривали вариант сбора и анализа логов от популярного веб-сервера Nginx. В данной статье настроим отправку логов в Graylog2 от docker-контейнеров - давайте разберемся!

Docker поддерживает более десятка различных механизмов логирования, которые позволяют получать информацию от запущенных контейнеров и сервисов. Эти механизмы называются logging drivers, ознакомиться с их полным списком можно здесь. Из данного списка нас больше всего интересует драйвер под названием gelf - остановимся на нем подробнее.

GELF - сокращение от Graylog Extended Log Format - специального формата логов, разработанного для Graylog. Этот формат получил широкое распространение и сейчас внедрен в множество других систем сбора, хранения и обработки логов (самые известные - Logstash и Fluentd).

Согласно стандарту GELF, в каждом лог-сообщении существует следующий набор полей:

  • версия;
  • хост (откуда пришло сообщение);
  • время (timestamp);
  • сокращенный и полный вариант сообщения;
  • другие поля, настроенные самостоятельно.

Иначе говоря, строка из лога:

127.0.0.1 - frank [10/Oct/2010:11:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

В GELF-формате может выглядеть, например, как структурированный json-объект (что в свою очередь значительно облегчает хранение и обработку логов):

{
  "client": "127.0.0.1",
  "user": "frank",
  "timestamp": "2010-10-10 11:55:36 -0700",
  "method": "GET",
  "uri": "/apache_pb.gif",
  "protocol": "HTTP/1.0",
  "status": 200,
  "size": 2326
}

Для использования gelf как драйвера по умолчанию в системе (параметр будет применен ко всем docker-контейнерам на этом хосте) необходимо в конфигурационном файле /etc/docker/daemon.json (в Windows это C:\ProgramData\docker\config\daemon.json) добавить следующие строки:

{
  "log-driver": "gelf",
  "log-opts": {
    "gelf-address": "udp://1.2.3.4:12201"
  }
}

Примечание. Вместо 1.2.3.4 конечно же нужно вставить реальный адрес вашего сервера Graylog.

И перезапустить docker для применения изменений:

service docker restart

Применить драйвер gelf только для одного конкретного контейнера при его запуске можно так:

docker run \
      --log-driver gelf –-log-opt gelf-address=udp://1.2.3.4:12201 \
      alpine echo 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, то настройка драйвера логирования для определенного контейнера будет выглядеть так:

...
### 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"
...

Для тех, кому важно подтверждение доставки (TCP) логов от docker-контейнеров в централизованную систему хранения у меня плохие новости:

Unfortunately, the GELF logging driver in Docker only supports UDP.

Однако из других приложений сделать это можно легко и непринужденно. Протестировать отправку логов в Graylog2 из консоли можно так:

echo -e '{"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' | nc -w 1 graylog.lc 12202

Подробнее о всех доступных опциях драйвера логирования gelf можно почитать здесь.

tweet Share