Я использую docker logs [имя-контейнера] для просмотра журналов определенного контейнера.

Есть ли элегантный способ очистить эти журналы?

Ответы (20)

Сначала плохой ответ. Из этот вопрос есть однострочный, который вы можете запустить:

echo "" > $(docker inspect --format='{{.LogPath}}' )

вместо echo есть попроще:

: > $(docker inspect --format='{{.LogPath}}' )

или есть команда усечения:

truncate -s 0 $(docker inspect --format='{{.LogPath}}' )

Я не большой поклонник ни того, ни другого, поскольку они напрямую изменяют файлы Docker. Удаление внешнего журнала могло произойти, пока докер записывает данные в формате json в файл, что приводит к неполной строке и нарушению возможности чтения любых журналов из журналов докеров cli. Для примера, см. этот комментарий к ответу duketwo:

после очистки файла журнала я получаю эту ошибку: ошибка от демона в потоке: Ошибка при захвате журналов: недопустимый символ '\ x00' ищет начало значения

Вместо этого вы можете настроить Docker для автоматической ротации журналов за вас. Это делается с помощью дополнительных флагов для dockerd, если вы используете по умолчанию драйвер ведения журнала JSON:

dockerd ... --log-opt max-size=10m --log-opt max-file=3

Вы также можете установить это как часть вашего файла daemon.json вместо изменения ваших сценариев запуска:

{
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

Эти параметры необходимо настроить с корневым доступом. Обязательно запустите systemctl reload docker после изменения этого файла, чтобы настройки были применены. Затем этот параметр будет использоваться по умолчанию для всех вновь созданных контейнеров. Обратите внимание, что существующие контейнеры необходимо удалить и воссоздать заново, чтобы получить новые ограничения журнала.


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

docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...

или в файле создания:

version: '3.7'
services:
  app:
    image: ...
    logging:
      options:
        max-size: "10m"
        max-file: "3"

Для дополнительной экономии места вы можете переключиться с драйвера журнала json на «локальный» драйвер журнала. Он принимает те же параметры max-size и max-file, но вместо хранения в json использует двоичный синтаксис, который быстрее и меньше. Это позволяет хранить больше журналов в файле того же размера. Запись daemon.json для этого выглядит так:

{
  "log-driver": "local",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

Обратной стороной локального драйвера является то, что внешние парсеры / пересылки журналов, зависящие от прямого доступа к журналам json, больше не будут работать. Поэтому, если вы используете такой инструмент, как filebeat для отправки в Elastic, или универсальный сервер пересылки Splunk, я бы отказался от «локального» драйвера.

У меня есть немного больше об этом в моей презентации Советы и хитрости.

sudo find /var/lib/docker/containers/ -type f -name "*.log" -delete

Используйте:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Вам может понадобиться sudo

sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

исх. Джефф С. Как правильно очистить логи для контейнера Docker?

Ссылка: Обрезка файла во время его использования (Linux)

Вы не можете сделать это напрямую с помощью команды Docker.

Вы можете либо ограничить размер журнала, либо использовать сценарий для удаления журналов, связанных с контейнером. Здесь вы можете найти примеры скриптов (читать снизу): Функция: Возможность очистки журнала журнала # 1083

Ознакомьтесь с разделом ведения журнала ссылки на файл docker-compose, где вы можете указать параметры (например, ротацию журнала и ограничение размера журнала) для некоторых драйверов ведения журнала.

В Docker для Windows и Mac, а также, вероятно, других, можно использовать опцию tail. Например:

журналы докеров -f --tail 100

Таким образом, отображаются только последние 100 строк, и вам не нужно сначала прокручивать 1 миллион строк ...

(And thus, deleting the log is probably unnecessary)

Не уверен, что это полезно для вас, но удаление контейнера всегда помогает.

Итак, если вы используете docker-compose для своей установки, вы можете просто использовать docker-compose down && docker-compose up вместо docker-compose restart. При правильной настройке (обязательно используйте монтирование томов для постоянных данных) таким образом вы не потеряете никакие данные.

Конечно, это больше, чем запрошено OP. Но бывают различные ситуации, когда другие ответы не могут помочь (при использовании удаленного сервера докеров или работе на компьютере с Windows доступ к базовой файловой системе является проприетарным и трудным)

Linux / Ubuntu:

Если у вас несколько контейнеров и вы хотите удалить только один журнал, но не другие.

  • (Если у вас есть такие проблемы, как «Permission denied», сделайте сначала sudo su.)
  • Список всех контейнеров: docker ps -a
  • Найдите желаемый контейнер и скопируйте ИДЕНТИФИКАТОР КОНТЕЙНЕРА. Пример: E1X2A3M4P5L6.
  • Папки контейнеров и настоящие имена длиннее, чем E1X2A3M4P5L6, но первые 12 символов приводят к docker ps -a.
  • Удалите только этот журнал: > /var/lib/docker/containers/E1X2A3M4P5L6*/E1X2A3M4P5L6*-json.log (Замените E1X2A3M4P5L6 на ваш результат !!)

Как видите, внутри / container находятся контейнеры, а журналы имеют то же имя, но с -json.log в конце. Вам просто нужно знать эти первые 12 символов, потому что * означает «что угодно».

Мне нужно было что-то, что я мог бы запустить как одну команду, вместо того, чтобы писать docker ps и копировать каждый идентификатор контейнера и запускать команду несколько раз. Я адаптировал ответ BMitch и подумал, что поделюсь, если кому-то это может пригодиться.

Смешивание xargs, похоже, дает то, что мне нужно здесь:

docker ps --format = '{{. ID}}' | \
  xargs -I {} sh -c 'echo> $ (docker inspect --format = "{{. LogPath}}" {})'

Это захватывает каждый идентификатор контейнера, указанный в docker ps (стирает ваши журналы для любого контейнера в этом списке!), передает его в xargs, а затем отображает пустую строку для замены пути к журналу контейнера.

Если вам нужно сохранить резервную копию файлов журнала перед их удалением, я создал сценарий, который выполняет следующие действия (вы должны запускать его с помощью sudo) для указанного контейнера:

  1. Создает папку для хранения сжатых файлов журнала в качестве резервной копии.
  2. Ищет идентификатор работающего контейнера (указанный в имени контейнера).
  3. Скопируйте файл журнала контейнера в новое место (папку на шаге 1), используя случайное имя.
  4. Сжать предыдущий файл журнала (для экономии места).
  5. Обрезает файл журнала контейнера до определенного вами размера.

Примечания:

  • Используется команда shuf. Убедитесь, что он есть в вашем дистрибутиве Linux, или замените его на другой генератор случайных чисел, поддерживаемый bash.
  • Перед использованием измените переменную CONTAINER_NAME, чтобы она соответствовала вашему работающему контейнеру; это может быть частичное имя (не обязательно точно совпадающее имя).
  • По умолчанию он обрезает файл журнала до 10 МБ (10 мегабайт), но вы можете изменить этот размер, изменив переменную SIZE_TO_TRUNCATE.
  • Он создает папку по пути: / opt / your-container-name / logs, если вы хотите хранить сжатые журналы в другом месте, просто измените переменную LOG_FOLDER.
  • Выполните несколько тестов перед запуском в производство.
#!/bin/bash
set -ex

############################# Main Variables Definition:
CONTAINER_NAME="your-container-name"
SIZE_TO_TRUNCATE="10M"

############################# Other Variables Definition:
CURRENT_DATE=$(date "+%d-%b-%Y-%H-%M-%S")
RANDOM_VALUE=$(shuf -i 1-1000000 -n 1)
LOG_FOLDER="/opt/${CONTAINER_NAME}/logs"
CN=$(docker ps --no-trunc -f name=${CONTAINER_NAME} | awk '{print $1}' | tail -n +2)
LOG_DOCKER_FILE="$(docker inspect --format='{{.LogPath}}' ${CN})"
LOG_FILE_NAME="${CURRENT_DATE}-${RANDOM_VALUE}"

############################# Procedure:
mkdir -p "${LOG_FOLDER}"
cp ${LOG_DOCKER_FILE} "${LOG_FOLDER}/${LOG_FILE_NAME}.log"
cd ${LOG_FOLDER}
tar -cvzf "${LOG_FILE_NAME}.tar.gz" "${LOG_FILE_NAME}.log"
rm -rf "${LOG_FILE_NAME}.log"
truncate -s ${SIZE_TO_TRUNCATE} ${LOG_DOCKER_FILE}

Вы можете создать задание cron для запуска предыдущего скрипта каждый месяц. Первый запуск:

sudo crontab -e

Наберите a на клавиатуре, чтобы войти в режим редактирования. Затем добавьте следующую строку:

0 0 1 * * /your-script-path/script.sh

Нажмите клавишу escape, чтобы выйти из режима редактирования. Сохраните файл, набрав : wq и нажав Enter. Убедитесь, что файл script.sh имеет разрешения на выполнение.

Чтобы удалить / очистить журналы контейнера докеров, мы можем использовать команду ниже

$ (docker inspect container_id | grep "LogPath" | cut -d "" "-f4) или $ (docker inspect имя_контейнера | grep "LogPath" | cut -d "" "-f4)

Как пользователь root попробуйте запустить следующее:

>  /var/lib/docker/containers/*/*-json.log

или

cat /dev/null > /var/lib/docker/containers/*/*-json.log

или

echo "" > /var/lib/docker/containers/*/*-json.log
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

Благодаря ответу @ BMitchя только что написал сценарий оболочки для очистки журналов всех контейнеров:

#!/bin/bash
ids=$(docker ps -a --format='{{.ID}}')
for id in $ids
do
        echo $(docker ps -a --format='{{.ID}} ### {{.Names}} ### {{.Image}}' | fgrep $id)
        truncate -s 0 $(docker inspect --format='{{.LogPath}}' $id)
        ls -llh $(docker inspect --format='{{.LogPath}}' $id)
done

Вы можете настроить logrotate для периодической очистки журналов.

Пример файла в /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}

Я предпочитаю этот (из решений выше):

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Однако я использую несколько систем (например, Ubuntu 18.x Bionic), где этот путь не работает должным образом. Docker устанавливается через Snap, поэтому путь к контейнерам больше похож на:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log

Docker для пользователей Mac, вот решение:

    1. Найти путь к файлу журнала по:

      $ docker inspect | журнал grep

    1. SSH в докер-машину (предположим, имя по умолчанию, в противном случае запустите docker-machine ls, чтобы узнать):

      $ docker-machine ssh по умолчанию

    1. Изменение на пользователя root (ссылка):

      $ sudo -i

    1. Удалить содержимое файла журнала:

      $ echo ""> log_file_path_from_step1

Вот кроссплатформенное решение для очистки журналов контейнера докеров:

docker run --rm -v /var/lib/docker:/var/lib/docker alpine sh -c "echo '' > $(docker inspect --format='{{.LogPath}}' CONTAINER_NAME)"

Вставьте это в свой терминал и измените CONTAINER_NAME на желаемое имя или идентификатор контейнера.

На моих серверах Ubuntu даже при использовании sudo я бы получил Невозможно открыть ‘/var/lib/docker/containers/*/*-json.log’ для записи: Нет такого файла или каталога

Но сработало прочесывание докеров, инспектирование и усечение ответов:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' `

Docker4Mac, решение 2018 года:

LOGPATH=$(docker inspect --format='{{.LogPath}}' )
docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- truncate -s0 $LOGPATH

Первая строка получает путь к файлу журнала, аналогичный принятому ответу.

Во второй строке используется nsenter, что позволяет запускать команды на виртуальной машине xhyve, которая выступает в качестве хоста для всех контейнеров докеров под Docker4Mac. Мы запускаем знакомую команду truncate -s0 $ LOGPATH из ответов, отличных от Mac.

If you're using docker-compose, the first line becomes:

local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q ))

и - это имя службы из вашего файла docker-compose.yml.

Спасибо https://github.com/justincormack/nsenter1 за трюк nsenter.

Вы также можете указать параметры log-opts в командной строке docker run, например:

docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest

или в docker-compose.yml, например,

my-app:
image: my-app:latest
logging:
    driver: "json-file"
    options:
        max-file: "5"
        max-size: 10m

Кредиты: https://medium.com/@Quigley_Ja/ rotating-docker-logs-keep-your-overlay-folder-small-40cfa2155412 (Джеймс Куигли)

2022 WebDevInsider