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

Thank you for reading this post, don't forget to subscribe!

Работа с логами (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",
И после чего, выполняем:
JavaScript
$ 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

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

vim Dockerfile

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

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

$ 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