Як правильно очистити журнали для контейнера Docker?


210

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

Чи є елегантний спосіб очищення цих журналів?


14
За стороною ви можете отримати розмір журналів черезsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Відповіді:


251

З цього питання є однолінійний запуск:

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

або є аналогічна команда скорочення:

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

Я не є великим прихильником жодного з них, оскільки вони безпосередньо змінюють файли Докера. Видалення зовнішнього журналу може статися, коли docker записує дані у формат json у файл, що призводить до часткового рядка та порушення можливості читання журналів із docker logsкліпу.

Натомість, ви можете мати Docker автоматично обертати журнали для вас. Це робиться за допомогою додаткових прапорів до докерда, якщо ви використовуєте за замовчуванням драйвер журналу 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"}
}

Ці параметри потрібно налаштувати з кореневим доступом. Переконайтеся, що запустіть a systemctl reload dockerпісля зміни цього файлу, щоб застосувати настройки. Цей параметр буде за замовчуванням для будь-яких новостворених контейнерів. Зауважте, існуючі контейнери потрібно видалити та відтворити для отримання нових обмежень журналу.


Подібні параметри журналу можуть бути передані до окремих контейнерів, щоб змінити ці параметри за замовчуванням, що дозволяє зберегти більше або менше журналів на окремих контейнерах. Зdocker run цього виглядає:

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-файлу, але замість зберігання в json він використовує швидший і менший бінарний синтаксис. Це дозволяє зберігати більше журналів у файлі одного розміру. Запис daemon.json для цього виглядає так:

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

Недоліком локального драйвера є зовнішні парсери / форвардери журналів, які залежать від прямого доступу до json-журналів більше не працюватимуть. Отже, якщо ви використовуєте такий інструмент, як filebeat, для надсилання Elastic або універсального експедитора Splunk, я б уникав "локального" драйвера.

Про це я дізнався трохи більше у своїй презентації Поради та рекомендації .


6
Я зробив це, service docker restart яке самостійно не спрацювало. Крім того, довелося створити нові контейнери до вступу в силу. тобто просто виведення старих контейнерів не застосовувалося для нового ведення журналу
Robbo_UK

Я використовую Docker 1.13.1, і 'docker inspect --format =' {{. LogPath}} '<id контейнера>' повертає нульову рядок ("") .... але я все одно отримую вихід з ' докерські журнали <ідентифікатор контейнера> '?!? Звідки це походить і як я це очищую ??
JD Allen

@JDAllen 1.13.1 довго не підтримує. У мене немає старої системи для перегляду їх результатів перевірки.
BMitch

Ще краще було б echo -n > .... У будь-якому разі, я хотів би мати можливість більш контролювати свої журнали. Наприклад, після перезавантаження докер-композиції я хотів би мати механізм робити щось із збереженими журналами.
NarūnasK

2
@AlexisWilke якщо ви зможете зупинити докер, ви, ймовірно, зможете зупинити свій контейнер. Якщо ви можете зробити останнє, то відтворення контейнера з параметрами журналу буде моєю порадою. У новому контейнері немає старих журналів, і нові журнали будуть прокатуватися автоматично, вирішуючи одночасно короткострокову та довгострокову проблему.
BMitch

227

Використання:

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

Можливо, вам знадобиться судо

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

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

Довідка: обрізка файлу під час його використання (Linux)


4
усікати: не вдається відкрити '/var/lib/docker/containers/*/*-json.log' для написання: Немає такого файлу чи каталогу
BTR Naidu

2
@BTRNaidu вам потрібно запустити його як root / sudo, вміст containersне доступний інакше.
шпидон

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- працював на мене
Джефф С.

7
Ігноруйте двох професіоналів вище. Якщо ви не впевнені, ви можете просто перевірити за допомогою "ls /var/lib/docker/containers/*/*-json.log", що робиться усіченим.
duketwo

1
після випорожнення журналу я отримую цю помилку:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol

42

У Docker для Windows та Mac, а також, ймовірно, і інших, також можна використовувати хвіст. Наприклад:

docker logs -f --tail 100

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

(Таким чином, видалення журналу, ймовірно, непотрібне)


12
Ідея полягає в тому, щоб очистити файли журналів, а не друкувати останні n рядків файлів журналів
Youssouf

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

4
Щоб отримати розмір колод sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", отримати лише загальний розмір журналівsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F

Чи є якісь проблеми з тим, що dockerd / aufs не знають і не можуть видалити повернені файли журналу?
ThorSummoner

Ця команда працювала для мене, тоді як інших команд у цьому ПЗ немає. Якщо це має значення, я запускаю Докер версії 18 на CentOS 7
Tundra Fizz

27

Ви можете налаштувати логротат, щоб періодично очищати журнали.

Приклад файлу в /etc/logrotate.d/docker-logs

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

і як я цим користуюся? це використовується за замовчуванням з docker run? файл /etc/logrotate.d/docker-logsне існує, я мушу його створити?
Carlos.V

Вам потрібно викликати утиліту logrotate (logrotate <config-file>), і вона прочитає вашу конфігурацію та запустить очищення. Ви також можете встановити це, наприклад, як роботу з cron.
AlexPnt

Проблема з цим полягає в тому, що він може бути неправильно синхронізований з тим, що робить докер. Використання докерного засобу, напевно, набагато розумніше. (the"log-opts" як показав BMitch)
Алексіс Вілке

12

Docker4Mac, рішення 2018 року:

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

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

Другий рядок використовує, nsenterщо дозволяє запускати команди в xhyveVM, що сервери як хост для всіх контейнерів докера під Docker4Mac. Команда, яку ми виконуємо, є знайомою truncate -s0 $LOGPATHз відповідей, що не мають Mac.

Якщо ви використовуєте docker-compose, перший рядок стає:

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

і <service>це ім'я служби з вашого docker-compose.ymlфайлу.

Дякуємо https://github.com/justincormack/nsenter1 за nsenterтрюк.


4
А для обрізання журналів усіх контейнерів ви можете використовувати підстановку оболонки, як показано в інших відповідях, тому це лише одна команда:docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- sh -c 'truncate -s0 /var/lib/docker/containers/*/*-json.log'
bradenm

11

Це неможливо зробити безпосередньо за допомогою команди Docker.

Ви можете або обмежити розмір журналу, або використовувати скрипт, щоб видалити журнали, пов’язані з контейнером. Ви можете знайти приклади скриптів тут (читайте знизу): Особливість: Можливість очищення історії журналу # 1083

Перегляньте розділ ведення журналу посилання на файл докер-композиційного довідника, де ви можете вказати параметри (наприклад, обертання журналу та обмеження розміру журналу) для деяких драйверів реєстрації.


7

Як користувач root , спробуйте виконати наступне:

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

або

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

або

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

6

На моїх серверах Ubuntu навіть як судо я отримав би Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Але розчісування докера перевіряє і скорочує відповіді:

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

2

Я вважаю за краще цей (із рішень вище):

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

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

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

1

Ви також можете надати параметри журналу опцій у 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-keeping-your-overlay-folder-small-40cfa2155412 (James Quigley)


Значення параметрів повинні бути вказані (тобто "5"і , "10m"відповідно), як показано тут для глобального файлу daemon.json, але це те ж саме для Докер-compose.yml. В обох випадках це вплине лише на новостворені контейнери.
Адріан Ш

@AdrianW: docker-compose.yml не потребує цитат. Це абсолютно різні формати файлів. І так, ви маєте рацію: команди "docker run" та параметри docker-compose впливають лише на новостворені контейнери - на відміну від відповіді, що має найбільше голосів, яка впливає лише на перезапущені демони dockerd і доступна лише через кореневий доступ. Моя відповідь повинна показувати набагато простіший і оновлений шлях, ніж редагування, ніж перезапуск всього процесу докерда.
Даг Баардсен

Без лапок, я отримую: ПОМИЛКА: для програми Неможливо створити контейнер для сервісного додатка: json: не вдається зняти маршальне число в полі Go Stru LogConfig.Config рядка типу Якщо я цитую так: "5"це працює. 10mРобота , не цитуючи дійсно.
Адріан Ш

Схоже, є різниця між Docker для Windows та Docker для Linux. На останньому я повинен вкласти значення в лапки. Не на колишньому. Оновлено опис, щоб відповідати обом. Дякуємо, @AdrianW
Dag Baardsen

0

Докер для користувачів Mac, ось таке рішення:

    1. Знайти шлях файлу журналу за:

      $ docker inspect | grep log

    1. SSH в докерну машину (припустимо, ім'я default, якщо ні, запустіть, docker-machine lsщоб дізнатися):

      $ docker-machine ssh default

    1. Змінити на root користувача ( посилання ):

      $ sudo -i

    1. Видаліть вміст файлу журналу:

      $ echo "" > log_file_path_from_step1


2
docker-машина не працює з Docker для Mac. Замість цього ви можете запустити "Docker запустити -ti -v / вар / Бібліотека / вантажник / контейнери: / вар / Inception CentOS Баш" , а потім "усічений --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Джамшид

Ви можете використовувати docker exec -it default shдля введення оболонки sh в контейнер. Однак багато контейнерів неявно не роблять sudoкоманду доступною.
Даг Баардсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.