Dockerコンテナーログを単一のファイルにリダイレクトする方法


110

Dockerコンテナーのすべてのログを単一のログファイルにリダイレクトして分析します。私は試した

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

しかし、これは2つの異なるファイルにログを提供します。私はすでに試しました

docker logs container > /tmp/stdout.log

しかし、それはうまくいきませんでした。

回答:


137

ログをリダイレクトする必要はありません。

デフォルトでは、Dockerはログを1つのログファイルに保存します。ログファイルのパスを確認するには、次のコマンドを実行します。

docker inspect --format='{{.LogPath}}' containername

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log

そのログファイルを開いて分析します。

ログをリダイレクトすると、リダイレクトの前にのみログが取得されます。ライブログを表示することはできません。

編集:

ライブログを表示するには、以下のコマンドを実行できます

tail -f `docker inspect --format='{{.LogPath}}' containername`

注意:

このログファイル/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logは、Dockerがログを生成しない場合にのみ作成され、ログがない場合、このファイルは存在しません。コマンドを実行docker logs containernameしても何も返さない場合と同じです。そのシナリオでは、このファイルは使用できません。


tail -f `docker inspect --format='{{.LogPath}}' myapp`-本当にJSONです
Adam

そのファイルがない場合は失敗します。dockerがログを生成しない場合、このファイルは作成されません。しかし、Dockerがログを生成する場合、このコマンドはライブログを表示するのに適しています。アダムに感謝します。他の人を助けるために私の答えにそれを追加します。
pl_rock

「デフォルトでは、Dockerはログを1つのログファイルに保存します。」-どのような状況で?Dockerホストで実行されているすべてのコンテナーが単一のファイルに出力を取得しますか?単一のコンテナ?
Chris Stryczynski

@ChrisStryczynski Dockerはコンテナごとにログファイルを作成します
Eddy Hernandez

126

このオプションはどうですか:

docker logs containername >& logs/myFile.log

質問で要求されたログはリダイレクトされませんが、特定のファイルに一度コピーされます。


私が間違っていない場合、このコマンドは基本的に、コンテナーが開始されたときからのすべてのログをmyFile.logsにコピーします。正しい。?
Sアンドリュー

@SAndrewは基本的にそうです!ただし、Dockerの新しいバージョンは変更される可能性があります。見え方docker logs --helpを確認するために
エディ・ヘルナンデス

38

docker logs -f <yourContainer> &> your.log &

説明:

  • -f(つまり--follow):既存のすべてのログを書き込み、次に来るすべてのログを記録し続けます(追跡します)。
  • &> 標準出力と標準エラーの両方をリダイレクトします。
  • おそらく、そのメソッドをバックグラウンドで実行したいので、 &
  • 出力とstderrを次の方法で分離できます> output.log 2> error.log(を使用する代わりに&>)。

9

dockerコンテナーから1つのログファイルにstdoutとstderrの両方をキャプチャするには、次のコマンドを実行します。

docker logs container > container.log 2>&1

8

複数のコンテナーがあり、ログを1つのファイルに集約する場合、fluentdなどのログアグリゲーターを使用する必要があります。fluentdは、Dockerコンテナーのロギングドライバーとしてサポートされています。

したがって、docker-composeでは、ロギングドライバーを定義する必要があります

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

2番目のステップは、fluentd confを更新して、サービス1とサービス2の両方のログに対応することです。

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

この構成では、ログをこのパスの単一ファイルに書き込むように要求しています
/fluentd/log/service/service.*.log

3番目のステップは、カスタマイズされたfluentdを実行して、ログをファイルに書き込み始めることです。

ステップバイステップの説明のリンクはこちらです

少し長いですが、ログファイルのパスなどをより詳細に制御でき、Docker Swarmでも適切に機能するため、正しい方法です。


1

Dockerはstdoutとstderrをマージするので、ログ出力を他のシェルストリームと同様に扱うことができます。現在のログをファイルにリダイレクトするには、リダイレクト演算子を使用します

$ docker logs test_container > output.log
docker logs -f test_container > output.log

出力をstderrおよびstdoutに送信する代わりに、アプリケーションの出力をファイルにリダイレクトし、そのファイルをコンテナーの外部の永続ストレージにマップします。

$ docker logs test_container> /tmp/output.log

Dockerはコマンドラインで相対パスを受け入れないため、別のディレクトリを使用する場合は、完全なパスを使用する必要があります。


1

Windowsで作業していて(私のように)PowerShellを使用している場合は、次の行を使用してstdoutand をキャプチャできますstderr

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

誰かのお役に立てば幸いです。


1
コンテナー名に基づいてすべてのコンテナーログをファイルに保存するには...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

私が使用する最も簡単な方法は、ターミナルでのこのコマンドです:

docker logs elk > /home/Desktop/output.log

構造は:

docker logs <Container Name> > path/filename.log

1

最初にコンテナIDを確認してください

docker ps -a

CONTAINER ID列の最初の行を確認できます。おそらく「3fd0bfce2806」のようになり、シェルに入力します

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

あなたはこのようなものを見るでしょう

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

その後、あなたはそれを

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

それはJSON形式になります。タイムスタンプを使用してエラーを追跡できます


0

すべてのコンテナーログを指定したディレクトリにコピーするBashスクリプト:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.