RailsをECSで動かす時のログをどうするか考える

May 4, 2020 by Yudai Suzuki

実験リポジトリ

制約

  • Fargate
  • リバースプロキシは別の Service で動いている
    • h2o, nginx など http server のログは考慮しない
  • Application Server は Unicorn

方針

  • Rails, Unicorn のログは全部 STDOUT に出す
    • STDOUT に両方のログがまとめて出る
  • Log Format は JSON
    • Unicorn のログ も JSON にする
  • ログは FireLens と fluent-bit 使っていい感じに集約する ログは全部CloudWatch Logsに吐いて、その先はKinesis Firehose

Rails, Unicorn のログは全部 STDOUT に出す

  • 環境変数 RAILS_LOG_TO_STDOUT を設定すれば STDOUT にログが出る
    • config/environment/production.rb にデフォルトで設定が書いてある
  • Unicorn の場合、RACK_ENVnone にしておかないと Rack::CommonLoggeruse されて余計なログが出ちゃうので設定しておく

Log Format は JSON

Rails

Rails でサクッと Log Format を JSON にする場合、 lograge を使うのがメジャーだが、一つ問題があり、Rack で処理されるリクエストがログに出なくなってしまう。

それを回避するために、 rails_semantic_logger を使う。

Unicorn

Unicorn の log の Formatter を変更するには、 Configurator::DEFAULTS[:logger].formatter をいじる。

require 'json'

Configurator::DEFAULTS[:logger].formatter = proc do |severity, timestamp, progname, msg|
  "#{JSON.dump(service: 'unicorn', severity: severity, timestamp: timestamp, progname: progname, msg: msg)}\n"
end

その他

  • フィルターするために、ログに識別子を追加しておく
    • "{ "service": "rails" }" みたいな
    • rails は config.log_tags に設定するのが楽
    • unicorn は Formatter の lambda の中で設定するのが楽

ログは FireLens と fluent-bit 使っていい感じに集約する ログは全部CloudWatch Logsに吐いて、その先はKinesis Firehose

firelensの送信先をCloudWatch Logsにすれば、の複数のコンテナのログを1つのLog Streamに集約してくれるかと思ったけど、してくれなかった。
そういうことがしたい場合、Datadog Logsとかに送った方がいいと思う。
まあS3に送ってAthenaで色々やりたいみたいな用途もあるから、firelensの用途は普通にあると思う。

-> 結局、CloudWatch Logsに全部流してCW Logs -> Kinesis Firehose -> S3 <- Athena が楽だと思った。 あとCW LogsからDatadogに送りたいけど無限に金がかかる。

© 2017 | Onigra | Powerd by Hucore theme & Hugo