#問題
node.jsでdockerコンテナのログを監視し、特定のログが出た場合に必要なアクションをとるようなアプリを作ろうとしたが、spawnでstdoutが上手く拾えなかった
#原因
ログの絞込みのためgrepを使用していたが、grepの出力がbufferされていて適切なタイミングでstdoutに出力されていなかった
#対応
grepのbufferを無効化するオプション(--line-buffered)を使用する。
サンプル
呼び出し元
app.js
const spawn = require('child_process').spawn
cmd = spawn('./tail.sh');
cmd.stdout.setEncoding('utf8');
cmd.stdout.on('data', (data) =>{
//アクション
console.log(data);
});
呼び出し先
tail.sh
docker logs -f --tail 0 コンテナ名 2>&1 | grep "監視文字列" -a --line-buffered
grepのオプション -a はつけなかった場合、"バイナリファイル (標準入力) に一致しました" とだけ標準出力に出力されてしまってログの内容が取れなかったのでその回避策でつけました
#まとめ
タイトルにはnode.jsやspawnと入れていましたが結局呼び出しているシェルの問題でした。grep以外にも各種コマンドや言語によって標準出力がデフォルトでbufferされていることがあるようなのでそれぞれにあったオプションをつける必要があるようです