Jak prawidłowo wyczyścić dzienniki dla kontenera Docker?

210

Używam docker logs [container-name]zobaczyć dzienniki konkretnego pojemnika.

Czy istnieje elegancki sposób na wyczyszczenie tych dzienników?

Youssouf Maiga
źródło
14
Na marginesie można uzyskać rozmiar dzienników za pośrednictwemsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Odpowiedzi:

251

Z tego pytania jest jedna linijka, którą możesz uruchomić:

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

lub istnieje podobne polecenie obcinania:

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

Nie jestem wielkim fanem żadnego z nich, ponieważ bezpośrednio modyfikują pliki Dockera. Zewnętrzne usuwanie dziennika może się zdarzyć, gdy doker zapisuje dane w formacie json do pliku, co powoduje częściową linię i przerywa zdolność do odczytu dowolnych dzienników z docker logscli.

Zamiast tego Docker może automatycznie obrócić dzienniki za Ciebie. Odbywa się to za pomocą dodatkowych flag do dockerd, jeśli używasz domyślnego sterownika logowania JSON :

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

Możesz również ustawić to jako część pliku daemon.json zamiast modyfikować skrypty startowe:

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

Te opcje należy skonfigurować z dostępem do konta root. Pamiętaj, aby uruchomić systemctl reload dockerpo zmianie tego pliku, aby zastosować ustawienia. To ustawienie będzie wówczas domyślne dla wszystkich nowo utworzonych kontenerów. Uwaga: istniejące kontenery należy usunąć i ponownie utworzyć, aby otrzymać nowe limity dzienników.


Podobne opcje dziennika można przekazać do poszczególnych kontenerów, aby zastąpić te wartości domyślne, co pozwala zapisać więcej lub mniej dzienników na poszczególnych kontenerach. Z docker runtego wygląda następująco:

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

lub w pliku tworzenia:

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

Aby zaoszczędzić miejsce, możesz przełączyć sterownik dziennika dziennika na „lokalny” sterownik dziennika. Przyjmuje takie same opcje maksymalnego rozmiaru i maksymalnego pliku, ale zamiast przechowywać w Json, używa składni binarnej, która jest szybsza i mniejsza. Umożliwia to przechowywanie większej liczby dzienników w pliku o tym samym rozmiarze. Wpis daemon.json dla tego wygląda następująco:

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

Minusem lokalnego sterownika jest to, że zewnętrzne parsery / forwardery dziennika, które zależą od bezpośredniego dostępu do dzienników json, przestaną działać. Więc jeśli używasz narzędzia takiego jak filebeat do wysyłania do Elastic lub uniwersalnego forwardera Splunk, unikałbym „lokalnego” sterownika.

Mam trochę więcej na ten temat w mojej prezentacji Porady i wskazówki .

BMitch
źródło
6
Zrobiłem coś, service docker restart co samo w sobie nie zadziałało. Musiał też stworzyć nowe kontenery, zanim zaczęły obowiązywać. tzn. samo
przywołanie
Korzystam z Docker 1.13.1, a 'docker inspect --format =' {{. LogPath}} '<identyfikator kontenera>' zwraca ciąg pusty („”) .... ale nadal otrzymuję dane wyjściowe z „ dzienniki dokera <identyfikator kontenera>? Skąd to się bierze i jak to wyjaśnić?
JD Allen
@JDAllen 1.13.1 już dawno nie jest obsługiwany. Nie mam tak starego systemu, aby wyświetlić wyniki inspekcji.
BMitch
Jeszcze lepiej byłoby echo -n > .... W każdym razie chciałbym mieć większą kontrolę nad moimi dziennikami. Na przykład po ponownym uruchomieniu komponentu dokującego chciałbym mieć mechanizm do zrobienia czegoś z zachowanymi dziennikami.
NarūnasK,
2
@AlexisWilke, jeśli możesz zatrzymać dokera, prawdopodobnie możesz zatrzymać swój kontener. Jeśli możesz zrobić to drugie, to odradzam pojemnik z opcjami rejestrowania byłby moją radą. W nowym kontenerze nie ma starych dzienników, a nowe dzienniki zostaną automatycznie zwinięte, rozwiązując jednocześnie problem krótko- i długoterminowy.
BMitch
227

Posługiwać się:

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

Możesz potrzebować sudo

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

ref. Jeff S. Jak prawidłowo wyczyścić dzienniki dla kontenera Docker?

Odwołanie: Obcinanie pliku podczas jego używania (Linux)

duketwo
źródło
4
obcinanie: nie można otworzyć „/var/lib/docker/containers/*/*-json.log” do zapisu: Brak takiego pliku lub katalogu
BTR Naidu
2
@BTRNaidu musisz uruchomić go jako root / sudo, zawartość containersnie jest dostępna w inny sposób.
spydon
25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- pracował dla mnie
Jeff S.
7
Zignoruj ​​dwóch wyżej wymienionych specjalistów. Jeśli nie masz pewności, możesz po prostu sprawdzić za pomocą „ls /var/lib/docker/containers/*/*-json.log”, co jest obcinane.
duketwo
1
po opróżnieniu pliku dziennika error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
pojawia
42

W Docker dla Windows i Mac oraz prawdopodobnie także innych, można użyć opcji tail. Na przykład:

docker logs -f --tail 100

W ten sposób wyświetlanych jest tylko 100 ostatnich linii i nie musisz najpierw przewijać linii 1M ...

(I dlatego usunięcie dziennika jest prawdopodobnie niepotrzebne)

Egbert Nierop
źródło
12
Chodzi o to, aby wyczyścić pliki dziennika i nie drukować ostatnich n wierszy plików dziennika
Youssouf Maiga
41
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Richard
źródło
4
Aby uzyskać rozmiar kłód sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", aby uzyskać łączną wielkość kłódsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F
Czy są jakieś problemy z tym, że dockerd / aufs jest nieświadomy i nie jest w stanie usunąć obróconych plików dziennika?
ThorSummoner,
To polecenie działało dla mnie, podczas gdy inne polecenia w tym SO nie działały. Jeśli to ma znaczenie, korzystam z Dockera w wersji 18 na CentOS 7
Tundra Fizz
27

Możesz skonfigurować program logrotate do okresowego czyszczenia dzienników.

Przykładowy plik w /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}
AlexPnt
źródło
i jak z tego korzystać? jest używany domyślnie z docker run? plik /etc/logrotate.d/docker-logsnie istnieje, muszę go utworzyć?
Carlos.V
Musisz wywołać narzędzie logrotate (logrotate <plik konfiguracyjny>), a on odczyta twoją konfigurację i uruchomi czyszczenie. Możesz również ustawić go jako zadanie cron, na przykład.
AlexPnt
Problem polega na tym, że może nie być odpowiednio zsynchronizowany z tym, co robi doker. Korzystanie z funkcji dokera jest prawdopodobnie znacznie mądrzejsze. ( "log-opts"jak pokazuje BMitch)
Alexis Wilke
12

Docker4Mac, rozwiązanie 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

Pierwszy wiersz pobiera ścieżkę do pliku dziennika, podobną do przyjętej odpowiedzi.

Drugi wiersz używa, nsenterktóry pozwala uruchamiać polecenia na xhyvemaszynie wirtualnej, która serwuje jako host dla wszystkich kontenerów dokerów w Docker4Mac. Polecenie, które wykonujemy, jest znane truncate -s0 $LOGPATHz odpowiedzi innych niż Mac.

Jeśli używasz docker-compose, pierwsza linia staje się:

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

i <service>jest nazwą usługi z twojego docker-compose.ymlpliku.

Dzięki https://github.com/justincormack/nsenter1 za nsenterlewę.

elifiner
źródło
4
Aby obciąć dzienniki wszystkich kontenerów, możesz użyć wieloznacznej powłoki, jak pokazano w innych odpowiedziach, więc jest to tylko jedno polecenie: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

Nie możesz tego zrobić bezpośrednio za pomocą polecenia Docker.

Możesz ograniczyć rozmiar dziennika lub użyć skryptu, aby usunąć dzienniki związane z kontenerem. Przykłady skryptów można znaleźć tutaj (czytaj od dołu): Funkcja: Możliwość wyczyszczenia historii dziennika # 1083

Zapoznaj się z sekcją dotyczącą rejestrowania w pliku referencyjnym dotyczącym tworzenia okna dokowanego, w którym można określić opcje (takie jak obrót i limit rozmiaru dziennika) dla niektórych sterowników rejestrowania.

Tristan
źródło
7

Jako użytkownik root spróbuj uruchomić następujące czynności:

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

lub

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

lub

echo "" > /var/lib/docker/containers/*/*-json.log
matson kepson
źródło
6

Na moich serwerach Ubuntu dostałbym nawet sudo Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Ale czesanie dokera w celu sprawdzenia i obcięcia odpowiedzi zadziałało:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`
Aqwan
źródło
2

Wolę ten (z powyższych rozwiązań):

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

Korzystam jednak z kilku systemów (na przykład Ubuntu 18.x Bionic), w których ta ścieżka nie działa zgodnie z oczekiwaniami. Docker jest instalowany przez Snap, więc ścieżka do kontenerów jest bardziej jak:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log
igraczech
źródło
1

Możesz także podać parametry log-opts w docker runwierszu poleceń, w następujący sposób:

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

lub w docker-compose.yml jak ten

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

Kredyty: https://medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412 (James Quigley)

Dag Baardsen
źródło
Wartości parametrów powinny być cytowane (tj. "5"I "10m"odpowiednio), jak pokazano tutaj dla globalnego pliku daemon.json, ale jest to to samo dla docker-compose.yml. W obu przypadkach wpłynie to tylko na nowo utworzone kontenery.
Adrian W
@AdrianW: docker-compose.yml nie potrzebuje cudzysłowów. Są to całkowicie różne formaty plików. I tak, masz rację: polecenia „uruchom dokera” i parametry tworzenia dokera wpływają tylko na nowo utworzone kontenery - w przeciwieństwie do odpowiedzi tutaj z największą liczbą głosów, która wpływa tylko na zrestartowane demony dockerd i jest dostępna tylko poprzez dostęp do konta root. Moja odpowiedź ma wskazywać znacznie prostszą i zaktualizowaną ścieżkę niż edytowanie niż ponowne uruchomienie całego procesu dockerd.
Dag Baardsen
Bez cudzysłowów otrzymuję: BŁĄD: dla aplikacji Nie można utworzyć kontenera dla aplikacji serwisowej: json: nie można oddzielić numeru do pola tekstowego Go struct LogConfig.Config typu ciągu Jeśli cytuję w ten sposób: "5"działa. 10mPraca bez cytowania rzeczywiście.
Adrian W
Wygląda na to, że istnieje różnica między Docker dla Windows a Docker dla Linux. W tym drugim przypadku muszę zawrzeć wartości w cudzysłowie. Nie na tym pierwszym. Zaktualizowano opis, aby pasował do obu. Dzięki, @AdrianW
Dag Baardsen,
0

Użytkownicy Dockera na komputery Mac, oto rozwiązanie:

    1. Znajdź ścieżkę do pliku dziennika według:

      $ docker inspect | grep log

    1. SSH do maszyny dokującej (załóżmy, że nazwa to default, jeśli nie, uruchom, docker-machine lsaby się dowiedzieć):

      $ docker-machine ssh default

    1. Zmień na użytkownika root ( odniesienie ):

      $ sudo -i

    1. Usuń zawartość pliku dziennika:

      $ echo "" > log_file_path_from_step1

Jinsong Li
źródło
2
docker-machine nie działa z Docker na Mac. Zamiast tego można uruchomić "run Döcker ti -v / var / lib / doker / zbiorniki: / var / Inception CentOS bash", a następnie "truncate --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Jamshid
Możesz użyć docker exec -it default shdo wprowadzenia powłoki sh w pojemniku. Jednak wiele kontenerów domyślnie nie udostępnia sudopolecenia.
Dag Baardsen