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

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);
  • сокра­щен­ный и пол­ный вари­ант сообщения;
  • дру­гие поля, настро­ен­ные самостоятельно.

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

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

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

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

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

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

При выпол­не­нии дан­ной коман­ды про­изой­дет следующее:

  • Docker Engine ска­ча­ет образ alpine из реджи­стри (если его нет локально);
  • Docker Engine создаст и запу­стит кон­тей­нер из обра­за alpine;
  • в запу­щен­ном кон­тей­не­ре выпол­нит­ся коман­да echo с аргу­мен­том hello world;
  • про­цесс внут­ри кон­тей­не­ра напи­шет hello world в stdout;
  • сооб­ще­ние hello world будет пере­хва­че­но Docker Engine и отправ­ле­но драй­ве­ру логи­ро­ва­ния (logging driver);
  • gelf драй­вер пере­ве­дет сооб­ще­ние в GELF-фор­мат (кро­ме стро­ки hello world доба­вит недо­ста­ю­щие поля hosttimestamp и набор инфор­ма­ции о кон­тей­не­ре - его ID и имя, имя и ID обра­за с кото­ро­го запус­кал­ся кон­тей­нер, пере­мен­ные окру­же­ния и т.д.);
  • сооб­ще­ние в GELF-фор­ма­те будет отправ­ле­но по про­то­ко­лу UDP на ip-адрес 1.2.3.4 порт 12201;
  • ско­рее все­го (это же UDP) сооб­ще­ние будет достав­ле­но на сер­вер Graylog2, где с ним мож­но будет работать.

Если вы опи­сы­ва­е­те несколь­ко кон­тей­не­ров в фай­ле docker-compose.yml, то настрой­ка драй­ве­ра логи­ро­ва­ния для опре­де­лен­но­го кон­тей­не­ра будет выгля­деть так:

[codesyntax lang="php"]

[/codesyntax]

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

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

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

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