dockerコンテナにつなげている場合、コンテナから出てくるログに対してパイプをつなげたいということが度々生じるが、実現するのにかなり苦労したので、備忘録として残しておく
grepでパイプラインさせる
コンテナログから最新のログを出し、垂れ流したい場合はこのようにします。-fのみだと全部出てくるため、--tailオプションも併用しています。
※ 出力したいコンテナ名をcontainer_nameとしています。
docker logs container_name -f --tail 1
これをgrepでパイプラインさせる場合は、以下のことに注意する必要があります。
- docker logsのログは
STDOUTおよびSTDERR双方に出力されることがあるため、|&でパイプラインさせる -
grepでは出力がバッファされてしまうので、--line-bufferedオプションもつけてバッファさせないようにしておく(ここでさんざんハマりました)
したがって、このようにすればgrepでパイプラインできるようになります。
docker logs container_name -f --tail 1 |& grep --line-buffered [ここに絞り込みたい条件を記載]
さらにjqでパイプラインさせる
docker logsの結果にjsonで流し込んでいる場合は、jqでパイプラインさせたいときがあります。
その場合は、以下のことに注意する必要があります。
- jsonの部分を取り出したいので、grepで抽出させる。もちろんバッファされないようにするため、
--line-bufferedも併用しておく - その結果をjqに入れるが、バッファさせないようにするため
--unbufferedオプションをつけておく
したがって、このようにすればjqでパイプラインできるようになります。
docker logs container_name -f --tail 1 |& grep --line-buffered -io '{.*}' | jq --unbuffered '.'