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のファイルを直接変更するので、どちらも大して好きではありません。外部ログの削除は、DockerがJSON形式のデータをファイルに書き込んでいるときに発生する可能性があり、その結果、行が部分的になり、docker logsCLI からログを読み取ることができなくなります。

代わりに、Dockerに自動的にログをローテーションさせることができます。これは、デフォルトのJSONロギングドライバーを使用している場合、dockerdへの追加のフラグで行われます。

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"}
}

これらのオプションは、rootアクセスで構成する必要があります。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-fileオプションを使用しますが、jsonに格納する代わりに、より高速で小さいバイナリ構文を使用します。これにより、同じサイズのファイルにより多くのログを保存できます。そのためのdaemon.jsonエントリは次のようになります。

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

ローカルドライバーの欠点は、jsonログへの直接アクセスに依存していた外部ログパーサー/フォワーダーが機能しなくなることです。そのため、filebeatなどのツールを使用してElasticまたはSplunkのユニバーサルフォワーダーに送信する場合、「ローカル」ドライバーは避けます。

ヒントとテクニックのプレゼンテーションで、これについてもう少し詳しく説明します。


6
私はservice docker restart それだけではうまくいかないことをしました。また、それが有効になる前に、新しいコンテナをブランド作成する必要がありました。つまり、古いコンテナを起動しただけでは新しいロギングが適用されませんでした
Robbo_UK '25

私はDocker 1.13.1を使用しており、 'docker inspect --format =' {{。LogPath}} '<container id>'はnull文字列( "")....を返しますが、 ' Dockerログ<コンテナーID> '?!?それはどこから来て、どうすればそれをクリアできますか?
JDアレン

@JDAllen 1.13.1はサポート対象外です。私は彼らの検査出力を見るための古いシステムを持っていません。
BMitch

さらに良いでしょうecho -n > ...。とにかく、自分のログをより詳細に制御できるようにしたいと考えています。たとえば、docker-composeの再起動後、保存されたログを使って何かを行うメカニズムが欲しいです。
NarūnasK

2
@AlexisWilke Dockerを停止できる場合は、おそらくコンテナーを停止できます。後者を実行できる場合、ロギングオプションを使用してコンテナを再作成することをお勧めします。新しいコンテナには古いログがなく、新しいログは自動的にローリングされるため、短期的な問題と長期的な問題の両方が同時に解決されます。
BMitch

227

使用する:

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

あなたはsudoが必要かもしれません

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

ref。Jeff S. Dockerコンテナーのログを適切にクリアする方法は?

リファレンス:使用中のファイルの切り捨て(Linux)


4
truncate: '/var/lib/docker/containers/*/*-json.log'を書き込み用に開けません:そのようなファイルまたはディレクトリはありません
BTR Naidu

2
@BTRNaiduをroot / sudoとして実行する必要がcontainersあります。それ以外の場合、コンテンツは利用できません。
スパイドン2017

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"-私のために働いた
ジェフS.

7
上記の2人の専門家は無視してください。不明な場合は、「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

WindowsとMac用のDocker、そしておそらく他のものでも、tailオプションを使用することが可能です。例えば:

docker logs -f --tail 100

この方法では、最後の100行のみが表示され、最初に100万行をスクロールする必要はありません...

(したがって、ログの削除はおそらく不要です)


12
アイデアは、ログファイルをクリーンアップし、ログファイルの最後のn行を印刷しないことです
Youssouf Maiga

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

このコマンドは私にはうまくいきましたが、このSOの他のコマンドはうまくいきませんでした。重要な場合、私はCentOS 7でDockerバージョン18を実行しています
Tundra Fizz

27

logrotateを設定して、定期的にログをクリアできます。

/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 2019

logrotateユーティリティ(logrotate <config-file>)を呼び出す必要があります。これにより、構成が読み込まれ、クリーンアップが実行されます。たとえば、cronジョブとして設定することもできます。
AlexPnt

これの問題は、Dockerの動作と適切に同期されない可能性があることです。Docker機能を使用する方がおそらく賢明です。("log-opts"BMitchが示すとおり)
Alexis Wilke

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

最初の行は、受け入れられた回答と同様に、ログファイルのパスを取得します。

2行目ではnsenterxhyveDocker4MacのすべてのDockerコンテナーのホストとして機能するVMでコマンドを実行できるようにしています。私たちが実行するコマンドは、truncate -s0 $LOGPATHMac以外の回答でおなじみです。

を使用している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

一部のロギングドライバーのオプション(ログローテーションやログサイズの制限など)を指定できるdocker-composeファイルリファレンスのロギングセクションを確認してください。


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サーバーではsudoとしても Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

しかし、Dockerを調べて答えを切り詰めるとうまくいきました:

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

2

私はこれを好みます(上記の解決策から):

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

1

次のdocker runように、コマンドラインでlog-optsパラメータを指定することもできます。

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ファイルについて示していますが、docker-compose.ymlについても同じです。どちらの場合も、新しく作成されたコンテナにのみ影響します。
エイドリアンW

@AdrianW:docker-compose.ymlには引用符は必要ありません。これらは完全に異なるファイル形式です。そして、はい、そうです。「docker run」コマンドとdocker-composeパラメーターは、新しく作成されたコンテナーにのみ影響します-再起動されたdockerdデーモンのみに影響し、ルートアクセスでのみ利用できる、最も投票数の多いここでの回答とは対照的です。私の答えは、dockerdプロセス全体を再起動するよりも、編集よりもはるかに単純で更新されたパスを表示することになっています。
Dag Baardsen

引用符がないと、次のエラーメッセージが表示されます:エラー:アプリのサービスアプリのコンテナーを作成できません:json:文字列型のGo構造体フィールドLogConfig.Configに数値を非整列化できません このように引用"5"すると、動作します。10m確かに引用せずに作業。
エイドリアンW

Docker for WindowsとDocker for Linuxには違いがあるようです。後者では、値を引用符で囲む必要があります。前者ではありません。両方に適合するように説明を更新しました。ありがとう、@ AdrianW
Dag Baardsen

0

MacユーザーのためのDocker、これが解決策です:

    1. 次の方法でログファイルのパスを検索します。

      $ docker inspect | grep log

    1. DockerマシンにSSHで接続します(名前がdefaultである場合は、実行docker-machine lsして確認します)。

      $ docker-machine ssh default

    1. rootユーザーに変更します(参照):

      $ sudo -i

    1. ログファイルの内容を削除します。

      $ echo "" > log_file_path_from_step1


2
docker-machineはDocker for Macでは動作しません。あなたが代わりに実行することができます"ドッキングウィンドウの実行を-ti -vは/ var / libに/ドッキングウィンドウ/コンテナ:は/ var /創業CentOSのbashの"その後"TRUNCATE --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
ジャムシード

docker exec -it default shコンテナにshシェルを入力するために使用できます。ただし、多くのコンテナーは、sudoコマンドを暗黙的に使用可能にしません。
Dag Baardsen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.