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?


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 .


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)


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)


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"

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
}

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ę.


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.


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

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>`

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

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)


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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.