2019年7月19日金曜日

LTSV 形式のログが出力されるアプリを docker fluentd ドライバでパースする方法

概要

前回 JSON 版を紹介しましたがそれの LTSV 版です

環境

  • macOS 10.14.5
  • docker 18.09.2

アプリ

LTSV を 1 行ごとに出力すれば、なんでも OK です

  • vim app.rb
require 'logger'
require 'securerandom'

unless ENV['LOCAL'] == "true"
  $stdout = IO.new(IO.sysopen("/proc/1/fd/1", "w"), "w")
  $stdout.sync = true
  STDOUT = $stdout
end
logger = Logger.new(STDOUT)
logger.formatter = proc do |severity, datetime, progname, msg|
  %Q|timestamp:#{datetime.to_s}\tmessage:#{msg}\n|
end

loop do
  logger.info(SecureRandom.uuid)
  sleep(3)
end
  • ruby app.rb
timestamp:2019-07-17 21:02:07 +0900 message:7ccf7e56-3682-4a67-81dd-7da28ee579d9 timestamp:2019-07-17 21:02:10 +0900 message:c0643812-24e5-4685-8242-35e05a075bef

こんな感じで出力されれば OK です

Dockerfile

あとはこれを docker 上で動作させるようにします

  • vim Dockerfile
FROM ruby

ADD . /home
WORKDIR /home

CMD ["ruby", "app.rb"]
  • docker build -t myapp .

fluentd コンテナ

特にプラグインはないので設定ファイルだけ作成します

  • vim fluent.conf
<source>
  @type forward
</source>

<filter docker.app>
  @type parser
  format ltsv
  keep_time_key true
  key_name log
  reserve_data true
</filter>

<match docker.app>
  @type stdout
</match>

ポイントは parser プラグインを使うところです
これで事前に LTSV のログをパースします
ちなみにログは log というキーに詰め込まれているので key_namelog を指定します
reserve_data true にするとパースされる前のログもその残ります
不要であれば false を設定しましょう
また keep_time_key true を設定すれば LTSV 内に timestamp 情報が含まれている場合パース後もその情報を emit してくれます

あとはコンテナを起動すれば OK です

  • docker run --rm -p 24224:24224 -p 24224:24224/udp -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -e FLUENTD_CONF=fluent.conf --name=fluentd fluent/fluentd

動作確認

まずアプリコンテナを起動しましょう

  • docker run -d --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag="docker.app" myapp

次に fluentd コンテナのログを確認します

  • docker logs -f fluentd

すると以下のようにログが表示されるのが確認できます

2019-07-17 12:06:27.093063700 +0000 docker.app: {"container_id":"36577545866d341713bdcf120a53ec169fcfab74d57bd4203ad06aa7bd8c32e5","container_name":"/heuristic_hypatia","source":"stdout","log":"timestamp:2019-07-17 12:06:27 +0000\tmessage:fe8b95d0-3570-40ff-ae88-e8343f63dc5c","timestamp":"2019-07-17 12:06:27 +0000","message":"fe8b95d0-3570-40ff-ae88-e8343f63dc5c"} 2019-07-17 12:06:30.098940200 +0000 docker.app: {"container_id":"36577545866d341713bdcf120a53ec169fcfab74d57bd4203ad06aa7bd8c32e5","container_name":"/heuristic_hypatia","source":"stdout","log":"timestamp:2019-07-17 12:06:30 +0000\tmessage:2570d74d-ee3a-44c8-8663-30014560ed06","timestamp":"2019-07-17 12:06:30 +0000","message":"2570d74d-ee3a-44c8-8663-30014560ed06"}

timestamp と message がパースされて key-value として登録されていることがわかります
reserve_data false にすれば log キーのパースされていない元データがなくなります
そちらのほうがすっきりする場合はあります

最後に

LTSV のログを docker fluentd ドライバでパースする方法を紹介しました
filter で処理したあとはちゃんと match で受け取るのを忘れないようにしましょう

参考サイト

0 件のコメント:

コメントを投稿