Как перенаправить журналы контейнера докеров в один файл?

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и она ничего не возвращает. В этом случае этот файл будет недоступен.

pl_rock
источник
tail -f `docker inspect --format='{{.LogPath}}' myapp`- это действительно JSON
Адам
он потерпит неудачу, если этого файла нет. означает, что если докер не сгенерирует журнал, этот файл не будет создан. но если докер генерирует журналы, эта команда удобна для просмотра журналов в реальном времени. спасибо Адам. добавляю его в свой ответ, чтобы помочь другим.
pl_rock
«Docker по умолчанию хранит журналы в одном файле журнала». - в каком контексте? Все контейнеры, запущенные на хосте докеров, выводятся в один файл? Единый контейнер?
Крис Стричинский,
@ChrisStryczynski Docker создает файл журнала для каждого контейнера
Эдди Эрнандес
127

Как насчет этого варианта:

docker logs containername >& logs/myFile.log

Он не будет перенаправлять журналы, запрошенные в вопросе, а копирует их один раз в определенный файл.

Эдди Эрнандес
источник
Если я не ошибаюсь, эта команда в основном скопирует все журналы с момента запуска контейнера для представления в myFile.logs. Право.?
S Andrew
@SAndrew в основном да! но новые версии Docker могут измениться. лучше увидеть, docker logs --helpчтобы быть уверенным
Эдди Эрнандес
39

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

Пояснение:

  • -f(т.е. --follow): записывает все существующие журналы и продолжает ( следует ) записывать все, что будет дальше.
  • &> перенаправляет как стандартный вывод, так и стандартную ошибку.
  • Вероятно, вы захотите запустить этот метод в фоновом режиме, поэтому файл &.
  • Вы можете разделить вывод и стандартный поток с помощью: > output.log 2> error.log(вместо использования &>).
juanmirocks
источник
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

Вторым шагом будет обновление fluentd conf для обслуживания журналов как для службы 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

и третьим шагом будет запуск настроенного fluentd, который начнет записывать журналы в файл.

Вот ссылка для пошаговых инструкций

Немного длинный, но правильный способ, поскольку вы получаете больший контроль над путем к файлам журналов и т. Д., И он также хорошо работает в Docker Swarm.

Абхишек Галода
источник
1

Поскольку Docker объединяет для нас stdout и stderr, мы можем обрабатывать вывод журнала как любой другой поток оболочки. Чтобы перенаправить текущие журналы в файл, используйте оператор перенаправления

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

Вместо отправки вывода в stderr и stdout перенаправьте вывод вашего приложения в файл и сопоставьте файл с постоянным хранилищем вне контейнера.

$ docker logs test_container> /tmp/output.log

Docker не принимает относительные пути в командной строке, поэтому, если вы хотите использовать другой каталог, вам нужно будет использовать полный путь.

Аниш Варгезе
источник
1

Если вы работаете в Windows и используете PowerShell (как я), вы можете использовать следующую строку для записи stdoutи stderr:

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

Надеюсь, это кому-то поможет!

mirind4
источник
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
Itssaifurrehman
источник
1

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

docker ps -a

Вы можете увидеть первую строку в столбцах CONTAINER ID. Вероятно, это выглядит как "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
Mugen
источник