Як перенаправити журнали контейнерів докера в один файл?


111

Я хочу перенаправити всі журнали мого докерного контейнера в один файл журналу, щоб проаналізувати їх. я намагався

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

але це дає журнал у двох різних файлах. Я вже пробував

docker logs container > /tmp/stdout.log

але це не спрацювало.

Відповіді:


137

Не потрібно перенаправляти журнали.

Docker за замовчуванням зберігає журнали до одного файлу журналу. Щоб перевірити команду запуску шляху файлу журналу:

docker inspect --format='{{.LogPath}}' containername

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log

Відкрийте цей файл журналу та проаналізуйте.

якщо ви будете перенаправляти журнали, ви отримаєте журнали лише перед перенаправленням. ви не зможете побачити журнали, що живуть.

Редагувати:

Щоб побачити журнали, ви можете запустити нижче команди

tail -f `docker inspect --format='{{.LogPath}}' containername`

Примітка:

Цей файл журналу /var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logбуде створений лише в тому випадку, якщо докер створює журнали, якщо немає журналів, тоді цього файлу не буде. це схоже колись, якщо ми запускаємо команду, docker logs containernameі вона нічого не повертає. У цьому сценарії цей файл буде недоступний.


tail -f `docker inspect --format='{{.LogPath}}' myapp`- це дійсно JSON
Адам

він не вийде, якщо цього файлу немає. означає, що якщо докер не генерує жодного журналу, цей файл не буде створений. але якщо докер генерує журнали, тоді ця команда добре бачити журнали. дякую Адамові. додавши його до моєї відповіді, щоб допомогти іншим.
pl_rock

"Докер за замовчуванням зберігає журнали до одного файлу журналу." - в якому контексті? Усі контейнери, що працюють на хості докера, отримують вихід в один файл? Єдиний контейнер?
Кріс Стричинський

@ChrisStryczynski Docker створює файл журналу на контейнер
Eddy Hernandez

127

Як щодо цього варіанту:

docker logs containername >& logs/myFile.log

Він не буде перенаправляти журнали, про які просили запитання, але скопіював їх один раз у певний файл.


Якщо я не помиляюся, ця команда в основному буде копіювати всі журнали, коли контейнер почав представлятись до myFile.logs. RIght.
S Андрій

@SAndrew в основному так! але нові версії Docker можуть змінитися. краще побачити, docker logs --helpщоб бути впевненим
Едді Ернандес

39

docker logs -f <yourContainer> &> your.log &

Пояснення:

  • -f(тобто --follow): записує всі існуючі журнали і продовжує ( слідує ) реєструвати все, що буде далі.
  • &> переспрямовує як стандартний вихід, так і стандартну помилку.
  • Ймовірно, ви хочете запустити цей метод у фоновому режимі, таким чином &.
  • Ви можете відокремити вихід і stderr, використовуючи: > output.log 2> error.log(замість використання &>).

9

Щоб захопити як stdout, так і stderr з вашого докерного контейнера в один файл журналу, виконайте наступне:

docker logs container > container.log 2>&1

8

Якщо припустити, що у вас є кілька контейнерів, і ви хочете об'єднати журнали в один файл, вам потрібно використовувати такий агрегатор журналів, як fluentd. fluentd підтримується як драйвер журналу для докерних контейнерів.

Отже, в docker-compose потрібно визначити драйвер журналу

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

Другим кроком буде оновлення вільної конфіденційності для обслуговування журналів як для служби 1, так і для служби 2

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

У цій конфігурації ми просимо записувати журнали до одного файлу в цей шлях
/fluentd/log/service/service.*.log

і третім кроком буде запуск налаштованої мови, яка почне писати журнали до файлу.

Ось посилання для покрокових інструкцій

Біт довгий, але правильний спосіб, оскільки ви отримуєте більше контролю над файлом журналу файлів тощо, і він добре працює і в Docker Swarm.


1

Оскільки Докер об'єднує stdout і stderr для нас, ми можемо ставитися до виходу журналу як до будь-якого іншого потоку оболонки. Щоб перенаправити поточні журнали у файл, використовуйте оператор перенаправлення

$ docker logs test_container > output.log
docker logs -f test_container > output.log

Замість того, щоб надсилати вихід у stderr та stdout, перенаправляйте вихідну програму на файл та перекладайте файл у постійне зберігання поза контейнером.

$ docker logs test_container> /tmp/output.log

Докер не прийме відносні шляхи в командному рядку, тому, якщо ви хочете використовувати інший каталог, вам потрібно буде використовувати повний шлях.


1

Якщо ви працюєте в Windows і використовуєте PowerShell (як я), ви можете використовувати наступний рядок для зйомки stdoutта stderr:

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

Я сподіваюся, що це комусь допоможе!


1
Щоб зберегти всі файли журналів контейнерів, виходячи з назви контейнера ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

Найпростіший спосіб, який я використовую, це команда на терміналі:

docker logs elk > /home/Desktop/output.log

структура:

docker logs <Container Name> > path/filename.log

1

Спочатку перевірте свій ідентифікатор контейнера

docker ps -a

Ви можете бачити перший рядок у стовпцях ідентифікатора CONTAINER. Можливо, це виглядає приблизно так: "3fd0bfce2806", а потім введіть його в оболонці

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

Ви побачите щось подібне

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

тоді ви можете бачити це як

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

Це було б у форматі JSON, ви можете використовувати часову позначку для відстеження помилок


0

Сценарій Bash для копіювання всіх журналів контейнерів у вказаний каталог:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.