Compose: Особенность: Возможность очистки истории журнала

Созданный на 9 мар. 2015  ·  145Комментарии  ·  Источник: docker/compose

Функция, которую я считал полезной с тех пор, как изначально использовал Fig, а теперь Compose, будет иметь возможность очищать историю журналов для контейнеров, управляемых Composed. Длительно работающие или «болтливые» контейнеры могут в конечном итоге создавать нежелательный шум журнала.

Я бы ожидал, что эту проблему решит следующая команда:
$ docker-compose logs --clear [service]

arelogs kinenhancement

Самый полезный комментарий

docker logs -c (clear) <container> было бы здорово.

+1

Все 145 Комментарий

Я не думаю, что это функция, поддерживаемая демоном докеров. Глядя на документы api, единственным вариантом было бы усечь возвращенные журналы до ограниченного количества строк на контейнер:

https://docs.docker.com/reference/api/docker_remote_api_v1.17/#get -container-logs

: +1: по этому вопросу. На самом деле я использую compose для разработки веб-сайта на Golang, Mongodb и nginx ... Через 5 дней после начала у меня есть длинные журналы, которые вызывают беспокойство. Каждый раз, когда я перезапускаю контейнеры, в журнал добавляется много строк.
@dnephin Я не понимаю, даете ли вы решение (которое я не понимаю :)) или если вы предлагаете проверить, возможно ли это с помощью api. Извините за мой плохой английский.

Docker 1.6 добавит поддержку драйверов ведения журналов, см. Https://github.com/docker/docker/pull/10568 (в настоящее время; JSON, syslog и «none»). Ведется работа по базовой ротации журналов; https://github.com/docker/docker/pull/11485

Приятно это слышать, большое спасибо :)

Спасибо за предысторию и обновление Docker 1.6 - с нетерпением жду этого!

docker logs -c (clear) <container> было бы здорово.

+1

+1 Действительно важно

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

+1

+1

+1

: +1:

+1

+2

+1

Для записи: в Docker 1.8 и docker-compose 1.4 уже существует метод ограничения размера журнала с помощью https://docs.docker.com/compose/yml/#log -driver и log-opt max-size:

  log_driver: "json-file"
  log_opt:
    max-size: "100k"
    max-file: "20"

@dmage Спасибо, именно то, что мне нужно.

+1000

+1 полюбил бы это

+1

Решение @dmage отлично подходит для нас. Те другие, кто ставит +1, что не так с решением, которое он дал?

@Rodeoclash - я думаю, что одним из вариантов использования для этого является повторное использование заданного набора контейнеров для нового запуска, то есть тестового запуска CI. Старые журналы не имеют отношения к новому запуску, поэтому clear перед следующей командой устранит путаницу.

+1

+1, то же самое, что и @rosskevin

Хорошо, чтобы резюмировать:

  • вы можете сделать это из файла создания (см. https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 касается возможности ограничить вывод команды logs
  • # 1756 закрывает контейнер для вторичного использования.

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

Не совсем понимаю, почему это закрыли. Как очистить журнал журнала?

Я добавить:

  log_opt:
    max-size: 50k

Чтобы ограничить длину журналов.

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

docker logs -c <container>

Что дает?

Я понимаю, как ограничить размер журнала, но как вы _чистите_ журнал?

Я не думаю, что очистка журнала поддерживается механизмом докеров, который и управляет журналами.

Возможно, с помощью специального драйвера журнала вы могли бы это сделать, но это было бы внешним для компоновки.

+1 за возможность смыть логи ...

+1

+1

+1

+1

+1 для команды очистки журнала.

+1 для команды очистки журнала

+1

+1

+1

: +1:

+1

+1

Взгляните на этот документ:
https://docs.docker.com/engine/admin/logging/overview/

docker-logs-clean.sh

#!/bin/bash

rm $(docker inspect $1 | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

Призыв:

sudo ./docker-logs-clean.sh <container-name>;

@sgarbesi, спасибо!
+1

+1 для команды очистки журнала

Закрыто в пользу?

Чтобы повторить мой комментарий с https://github.com/docker/compose/issues/1083#issuecomment -149357280:

Хорошо, чтобы резюмировать:

  • вы можете сделать это из файла создания (см. https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 касается возможности ограничить вывод команды logs
  • # 1756 закрывает контейнер для вторичного использования.

Если вы ищете какую-то команду вроде docker logs --clear , которая не поддерживается механизмом докеров, вам нужно будет запросить ее в докере / докере. Однако я думаю, что перечисленных выше вариантов уже должно хватить для большинства случаев. Большинство людей хотят просто показать часть журналов, а не удалять их.

Спасибо @dnephin и всем остальным за их вклад. Я поднял этот вопрос почти год назад, и, судя по комментариям с тех пор, мне кажется довольно очевидным, что управление журналами - это проблема для многих пользователей Compose.

Было упомянуто несколько обходных путей, я в основном использую max-size чтобы сохранить журналы до разумной длины. Это очень помогает, и я благодарен за эти обходные пути, но важно помнить, что это обходной путь, а не решение.

Теперь мне также ясно, что часть ответственности за исправление этого лежит в системе ведения журналов Docker и что ей потребуется предоставить команду clear для использования Compose - достаточно справедливо.

При этом, однако, есть несколько функций, которые вошли в выпуски Docker с момента создания этого билета, а именно --since=<timestamp> и --tail=<num-lines> которые могут поддерживаться Compose, чтобы приблизиться к реальной решение этого вопроса.

Например, поддержка --since может сделать что-то вроде этого возможным:

$ docker-compose logs --since=now my_container

или же

$ docker-compose logs --since=5m my_container

Также будет полезна поддержка --tail , например

$ docker-compose logs --tail=100 my_container

и, конечно же, их комбинации. Также может иметь смысл поддержать их в docker-compose.yml как часть блока logging , но даже без этого, просто поддерживая эти два варианта, я подозреваю, вы могли бы удовлетворить большинство людей, у которых есть + Я купил этот билет.

Таким образом, еще раз спасибо за все отзывы и обходные пути, а также за сами Docker и Compose - они оба отличные продукты - я надеюсь, что вы примете во внимание идеи, выдвинутые в этом потоке, и продолжите делать эти продукты еще лучше.

См. # 2227 для сводки

: +1: спасибо @dnephin , с нетерпением жду этого!

Я вручную удалил файлы <container-id>-json.log помещенные внутри /var/lib/docker/containers/<container-id>/ (используйте sudo ). Как только я запустил docker-compose logs , журнал был пуст. Это не решение, но с правильным файлом .bash вы можете автоматизировать очистку перед каждой сборкой.

Изменить: что-то вроде этого помогает (используйте на свой страх и риск !!):

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

+1

+1

+1

+1

+2

+2

+1

+20

+1

+1

+1

+1

@sgarbesi После запуска этой чистой команды функция журнала будет работать нормально?

+1

docker-logs-clean.sh

#!/bin/bash

for container_id in $(docker ps -a --filter="name=$name" -q);

    do file=$(docker inspect $container_id | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

    if [ -f $file ]
      then
          rm $file;
    fi

done

Призыв:


chmod +x docker-logs-clean.sh

sudo ./docker-logs-clean.sh

+1 для опции командной строки для очистки логов вручную

@kassanmoor Делает для меня.

+1

Спасибо за другие способы очистки журналов контейнеров

👍

+1 👍

+1!

+1

+1

+1

Это было бы отличной функцией, у меня есть несколько контейнеров, основанных на Java, и даже через день или два при устранении неполадок может потребоваться 30 секунд или больше, чтобы выполнить docker logs -f <container> потому что Java любит эти многострочные журналы.

Еще одна вещь, которую может быть проще реализовать, - это еще один флаг в журналах для запуска хвоста, например, без повторения всех существующих журналов docker logs -f -n <container> (что означает отслеживание только новых журналов). Это будет отражать только сообщения журнала, полученные после выполнения команды.

Противоположный вариант также будет работать (и будет ближе к тому, как работает gnu tail): по умолчанию -f отображает последние 5-10 строк, а затем новые строки и добавляет флаг, чтобы отобразить все, как сейчас (возможно, docker logs -f -a <container> или что-то в этом роде).

В этой заметке я хотел бы иметь функцию от gnu tail, которая позволяет указывать количество строк в хвосте, например docker logs -100 <container> дает мне последние 100 строк.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Есть ли уловка для Docker для Mac? Спасибо и +1 за параметр командной строки для этого :)

+1

+1

+1

ОБНОВЛЕНИЕ: 2016/10/08 - Удалено требование для «jq», поскольку «журналы докеров» поддерживают шаблоны Go! (https://docs.docker.com/engine/admin/formatting/)

Привет всем,

Потому что удаление файлов, которые могли быть открыты, - это вообще ПЛОХАЯ идея, особенно если вы пытаетесь сэкономить место на диске! - Я расширил начальные усилия @sgarbesi , @lvitals и @wazoo (спасибо за идеи, ребята), чтобы создать чуть более функциональный сценарий ниже.

Скопируйте приведенный ниже код в файл
vi ./docker-container-log-trim.sh
Сделайте файл исполняемым
chmod +x ./docker-container-log-trim.sh
Затем выполните с
sudo ./docker-container-log-trim.sh

Раскомментируйте строку с > если вы доверяете сценарию ... вот где происходит волшебство. :-)

Обратная связь приветствуется.
Благодарю.

PS. Проверено, но не закалено. Используйте на свой страх и риск.

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z $1 ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$logfile $(docker inspect --format '{{ .LogPath }}' $container)"
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} $logfile > $TEMP
      # Uncomment the next line when you trust the script!
      # cat $TEMP > $logfile
    done
  fi

  rm $TEMP
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

+1

+1

Итак, поскольку неоднократно говорилось о том, что есть желание явной команды очистки, и поскольку она никогда не добавлялась, есть ли шанс, что она будет снова открыта?

Конечно, это зависит от изменения движка докеров, но это все же то, что в конечном итоге нужно будет решить и в docker-compose - и это определенно не исправлено в том, что касается явной команды.

@DavidPesticcio Я получаю эту ошибку при запуске вашего скрипта: line 53: $logfile: ambiguous redirect (после удаления комментария)

Привет @gingerlime! Похоже, что $ TEMP не заполняется ... может быть, у вас не установлен "mktemp" или он не на вашем пути? : - /

"У меня работает нормально" - да, я знаю, вам это не сильно поможет, но это правда ... :-)

Я обновил скрипт, так что вам больше не нужен "jq" - возможно, мне следует добавить спасение, если mktemp тоже отсутствует ... Я думал, что это стандартный инструмент - но, возможно, вы не используете скрипт в "стандартной" установке - может быть, из минимального контейнера? :-)

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

У меня есть mktemp , и я часто им пользуюсь ... На самом деле не тратил много времени на отладку. Закончился более простым скриптом выше, который просто уничтожает эти журналы. В нашей среде разработки они не важны.

в моей настройке (т.е. при работе без пользователя root) этот сценарий bash не помогает, потому что я получаю отказ в разрешении при попытке открыть файл журнала.

немного странно, что как пользователь я могу запустить докер, но могу записать его файлы журнала ...
еще одна причина, чтобы что-то потратить на команды docker / docker-compose

Мне пришлось изменить сценарий @DavidPesticcio из-за ошибок, упомянутых ранее ... вот оно:

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z "$1" ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$(docker inspect --format '{{.LogPath}}' $container)"
      if [ ! -f "$logfile" ]; then continue; fi
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} "$logfile" > "$TEMP"
      # Uncomment the next line when you trust the script!
      # cat "$TEMP" > "$logfile"
    done
  fi

  rm "$TEMP"
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

@dnephin есть ли шанс, что это можно будет открыть

Обрезать журналы для данного контейнера (должен быть root):

cp /dev/null $(docker inspect -f '{{.LogPath}}' container_name)

Вам нужно усечение, а не удаление. (Удаление файла, на который ссылается дескриптор открытого файла, не освобождает место до тех пор, пока процесс, в данном случае демон Docker, полностью не завершится)

@oogali достаточно честно. Тем не менее было бы неплохо иметь правильную команду, чтобы он делал это по запросу.

+1

было бы неплохо иметь для этого правильную команду

+1
было бы неплохо иметь соответствующую команду, чтобы он делал это по запросу.

Это простая задача, установка даты начала в качестве фильтра - это больше работы, чем просто ее очистка для просмотра текущего вывода. Пожалуйста, добавьте эту функцию.

+1

+1

+1

+1

+1

Тангенциально связанное предложение:

При выполнении docker-compose logs -f автоматически по умолчанию используется --tail=30 (или любое другое разумное число)

docker-compose logs -f недостаточно, потому что при большом количестве отображаемых журналов это занимает очень много времени

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Или есть этот обходной путь

logpath=`docker inspect --format='{{.LogPath}}' reveelium_metricsextraction_1` && mv $logpath $logpath".bckup"

Пожалуйста, перестаньте комментировать +1. Это делает эту ветку действительно трудной для чтения и извлечения ценной информации. Для этого на посте OP есть кнопка с изображением большого пальца вверх.

У меня здесь ничего не работает с Docker для Mac. Однако я собрал кое-что, что работает, основываясь на чтении этой ветки и форумов докеров.

Проблема с D4M в том, что на Mac вам нужно запускать команды на xhyve vm. Итак, вот что я придумал. Добавьте эти две функции в свой .bash_profile .

Важно : не забудьте запустить новую оболочку или перезагрузить профиль, прежде чем продолжить.


Теперь docker-logs-clean выглядит так:

#!/bin/bash -e

if [[ -z $1 ]]; then
    echo "No container specified"
    exit 1
fi

logFile=$(docker inspect -f '{{.LogPath}}' $1 2> /dev/null)

echo -n "Cleaning ${logFile}... "
d4mexec << EOF
> $logFile
EOF
echo "done"

Обратите внимание, что я не обрабатываю файл журнала rm , а просто выполняю > , что полностью обрезает файл.

FWIW в docker-compose версии 2 функция ограничения размеров файлов журнала:

version: '2'
services:
  my-service:
    image: nginx:alpine
    restart: always
    logging:
      # limit logs retained on host to 25MB
      driver: "json-file"
      options:
        max-size: "500k"
        max-file: "50"

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

+1

+1

+1

+1

+1

Я сделал простой скрипт docker_clear_log.sh :
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' $1)
Использование: ./docker_clear_log.sh [Имя-или-ID]
Должно работать, если у вас есть права sudo и параметр log_driver: "json-file" для вашего докера (по умолчанию).

+1

Я также пробовал временное решение, и оно, похоже, работает

Исходная проблема так и не была решена, и проблема все равно была закрыта. Интересно. @djessup , как тебе эти яблоки?

все равно было бы неплохо иметь журналы для создания докеров --clean

Почему этот вопрос был закрыт без комментариев, если проблема сама по себе не решена?

@linvi

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

https://github.com/docker/compose/issues/1083#issuecomment -149357280

Я думаю, они надеются охватить этот конкретный вариант использования косвенными средствами. Упомяните, что ваш конкретный вариант использования и что он не покрыт, и это может помочь повторно открыть заявку. В худшем случае кто-то может указать простой способ получить желаемое: D

Любые обновления?

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

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

Если вы используете docker-compose, используйте lazydocker для просмотра журналов. Тогда нет необходимости удалять журналы. Вы получаете живые журналы и начинаете с последних журналов. Это очень помогает при отладке.

grafik

https://github.com/jesseduffield/lazydocker
Вы можете установить его одной строкой, и это хороший инструмент для мониторинга. Жалко, что люди не так разумно понимают, что функция «удалить журнал» - это хорошо.

Но обходной путь с ленивым докером делает это за меня. Спасибо, jesseduffield, за предоставленную нам возможность полениться с вашим инструментом мониторинга :-)
Может быть, подумайте о пожертвовании lazydocker, если это также упростит вам отладку / мониторинг.
А для вас разработчики / сопровождающие докеров: почему интерфейс у докера не такой?
Докер довольно хорош, но взгляните на lazydocker; есть возможности для улучшения.

+2147483647

+49324893

Была ли эта страница полезной?
0 / 5 - 0 рейтинги