Работа с логами (Logs) в Docker

Работа с логами (Logs) в Docker

Логи в докере нужны в первую очередь для траблшутинга тех или иных проблем которые возникают у вас в ходе работы с контейнером.

Надеюсь что у вас уже имеется докер на хостевой машине, если нет, вот полезные статьи:

Установка Docker на Debian/Ubuntu

Установка Docker на CentOS/RedHat/Fedora

Установка docker-compose в Unix/Linux

Запуск docker контейнеров в Unix/Linux

Установка docker machine в Unix/Linux

Настройка docker swarm кластера в Unix/Linux

Запуск GUI-приложения в Docker

Запустить bash/SSH в контейнере с Docker

Создание base image для docker в Unix/Linux

Создание docker контейнера в Unix/Linux

Остановить/Удалить все Docker контейнеры/images

Работа с сетью (Networking) в Docker

Работа с томами (Volumes) в Docker

И так, приступим.

Работа с логами (Logs) в Docker

-=== СПОСОБ 1 ===-

Стандартное использование будет следующим:

$ docker logs $(docker ps -aql)

Version:    v0.4.9
Git commit: c4de4ad0
OS/Arch:    linux/amd64
Built:      Wed Aug 29 12:32:14 2018
time="2018-10-31T10:58:45Z" level=info msg="Controller ready"

Или если задали контейнер_нейм:

$ docker logs vault

-=== СПОСОБ 2 ===-

Логи монтируются на хостевую машину, по этому гегко понять где лежат логи:

$ docker inspect vault | grep -E "LogPath"
        "LogPath": "/var/lib/docker/containers/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b-json.log",

И после чего, выполняем:

$ cat /var/lib/docker/containers/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b-json.log

-=== СПОСОБ 3 ===-

Иногда бывает так, что приложенько не умеет выводить логи. Рассмотрим наглядный пример. Запустим контейнер:#

$ docker run -d -P myhttpd:latest
791c65b5aed05a11a40a953779675b5b94d090e691730c5c0bceaa33143fcbc4

Пробуем поулчить логи:

$ docker logs $(docker ps -lq)
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.17. Set the 'ServerName' directive globally to suppress this message

Как видно с вывода, докер не может считать логи с контейнера. Первое что приходит в голову, — это не рабочий контейнер, да? Но пробуем получить данные:

$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2)
my httpd container

Этим самым, видно что контейнер работает, но все еще не может отдавать логи.

Делов в том, что логи для Nginx лежат:

$ docker run nginx ls -l /var/log/nginx
total 0
lrwxrwxrwx 1 root root 11 Oct 2 19:20   access.log  -> /dev/stdout     
lrwxrwxrwx 1 root root 11 Oct 2 19:20   error.log -> /dev/stderr

Для Apache лежат вот тут:

# docker run httpd cat conf/httpd.conf | egrep '^ *(Error|Custom)Log'
ErrorLog /proc/self/fd/2
   CustomLog /proc/self/fd/1 common

Пофиксим это дело следующим образом, в докерфайл (нужно дописать\переопределить вывод):

FROM centos
LABEL maintainer="Vitaliy Natarov"
RUN yum install -y httpd web-assets-httpd && yum clean all
RUN echo "logs are sending to stdout" > /var/www/html/index.html

RUN ln -s /dev/stdout /var/log/httpd/access_log && \ 
    ln -s /dev/stderr /var/log/httpd/error_log

EXPOSE 80 
CMD httpd -DFOREGROUND

Билдаем образ:

$ docker build -t myhttpd:2.0 .

Запускаем контейнер:

$ docker run -d -P myhttpd:2.0
1b0c3a82d0687519ffcd2ee06d345a4d3ad8d475dc0d7710fb279bdd836e5e88

Проверим:

$ docker logs $(docker ps -lq)

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.17. Set the 'ServerName' directive globally to suppress this message

Дернем курл:

$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2)
logs are sending to stdout

И прверим что пишется в лог:

$ docker logs $(docker ps -lq)
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using
172.17.0.18. Set the 'ServerName' directive globally to suppress this message
172.17.0.1 - - [29/Jul/2018:22:07:24 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"

Ага! То что нужно было! Вот такой вот юзкейс.

Настройка  Log Driver

Запустим контейнер с заданным именем и лог-драйвером, например:

$ docker run -d -P --name=myhttpd --log-driver=journald myhttpd:2.0 
5748f3078b647c43a335bdc1f8bc7c8d9db31a491e635effd58b31b1429c8ee7

Проверим что вышло:

$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2)
logs are sending to stdout

Получите log-и контейнера через journald ( с указанием CONTAINER_NAME), например:

# journalctl -b CONTAINER_NAME=myhttpd
-- Logs begin at Sat 2018-07-28 19:14:07 BST, end at Sun 2018-07-29 23:19:52 BST. --
Jul 29 23:19:29 localhost.localdomain 5748f3078b64[2806]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.
Jul 29 23:19:50 localhost.localdomain 5748f3078b64[2806]: 172.17.0.1 - - [29/Jul/2018:22:19:50 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"

Запускаем кнтейнер с log-driver-ом и log-tag-ом:

$ docker run -d -P --log-driver=journald \
--log-opt tag=myhttpd \
myhttpd:latest
0555d7a41ab6af098dfea296e2fa7b4f1c6b73424e2156c387930b13bfcefb24

Чекаем:

$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2)
   logs are sending to stdout

С такой командой, теперь можно получить логи через указанный тег:

$ journalctl -b CONTAINER_TAG=myhttpd

Поддерживаемые Log Driver-ы:

  • none — Логи не доступны для контейнера, и логи самого докера не возвращают никакого вывода.
  • json-file- Log-и отформатированы как JSON. Данный драйвер используется по умолчанию в Docker.
  • syslog — Записывает логи в syslog. Демон syslog должен быть запущен на самом хосте.
  • journald — Записывает логи в journald. Демон journald должен быть запущен на самом хосте.
  • gelf — Записывает сообщения в Graylog (GELF) или Logstash.
  • fluentd — Записывает сообщения на fluentd (forward input). Демон fluentd должен быть запущен на самом хосте.
  • awslogs- Записывает сообщения в Amazon CloudWatch.
  • splunk — Записывает сообщения в splunk с помощью сборщика HTTP событий (HTTP Event Collector).
  • gcplogs — Записывает сообщения в Google Cloud Platform (GCP).
  • logentries — Записывает сообщения в Rapid7 Logentries.

Проверим что используется поумолчанию:

$ docker info --format '{{.LoggingDriver}}'
json-file

Меняем на нужный:

# cat << EOF > /etc/docker/daemon.json {
"log-driver": "journald" }
EOF

Перезапустим сервисы:

# systemctl daemon-reload && systemctl restart docker.service

Проверяем, изменилось ли у нас что-то:

$ docker info --format '{{.LoggingDriver}}'
journald

Можно запустить контейнер:

$ docker run -d -P --name=myweb --log-opt tag=myweb_tag myhttpd:2.0

Проверим логи одним из способов:

$ journalctl -b CONTAINER_NAME=myweb
$ journalctl -b CONTAINER_TAG=myweb_tag

Вот и все, статья «Работа с логами (Logs) в Docker» завершена.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.