GKE上RailsのアプリケーションログをStackdriver Loggingで運用する方法
弊社もpaymoサービスローンチ当初はAWS環境の仮想マシンに上に普通にRailsアプリケーションをデプロイしていましたが、現在では新規開発は全てGKE (Kubernetes Engine) + Docker上で動作しており、既存インフラも全て環境移行を実施しています。
当然、GKE (Kubernetes Engine) 上で本番運用するためには、コンテナや Stackdriver Logging を意識したログの出力が必要になります。意外とWeb上を検索してみても具体的な公開事例があまり見つからなかったため、現在弊社でのRailsログの運用状況について今回ご紹介したいと思います。
Railsのログの仕組み
Railsインフラ構成を下記と仮定します。
Rails + Unicorn > Nginx
上記構成の場合、アプリケーションサーバ関連のログはデフォルトでは以下にログが出力されます。
- log/development.log
- log/unicorn.stdout.log
上記以外にも個別出力しているファイルがあればそれも出力されると思います。これをGKE + Stackdriver Logging 上で動かすためには以下の2点の対応が必要になります
- 標準出力にログとして出力すること
- Stackdriver Logging に対応したJSON形式でログを出力すること
以下構成でPodを組んでいる前提で、Rails側について解説いたします。
- Rails + unicorn (FROM 2.3.7-alpine)
- nginx
GKE上でのログ運用方法
GKE環境にてアプリケーション運用する場合、基本的にログ管理はStackdriver Loggingを利用することになると思います。RubyアプリケーションをStackdriver Loggingに対してログを転送する方法は以下2点の方針が考えられます。
- google-cloud-ruby gem を利用して、API経由でログを保存する
- 標準出力
(1) であるGoogle Cloud公式の google-cloud-ruby のみの利用も検討いたしましたが、ログとして送信される情報量が多くなってしまう問題がありました。またシステムの結合度や負荷の観点からも、シンプルに標準出力に任意の形式で出力したほうが良いと判断し、通常のアプリケーションログとしては今回 (2) を採用しました。
アプリケーションログ標準出力に出す
GKE上では標準出力に出てきた内容を自動的に Stackdriver Logging と連携してくれます。さらに Stackdriver Logging ではJSON形式のログを受け付けると特定キーをフィルタ対象に出来るような形でパースして保存してくれます。
今回は一旦全てを標準出力に切り替え、今までファイル名で行っていたログ分類はJSONのvalueの一部として送信することにしました。
1. Rails
application.rb
に以下を設定します。
INFO
DEBUG
などのログレベルである severity
は Rails と Stackdriver Logging に互換性があるので、そのまま渡してあげるだけでOKです。Stackdriver Logging 側では特定の予約キー名のJSONを受け取ると取り込む機能があり、その一つが severity
になっています。今回の設定を組み込むことで、ログのビジュアライズとログレベルの分類を自動的に Stackdriver Logging 側で実施してくれます。
弊社ではrequest_id
もログに埋め込んでいるので、検索可能なようにJSONログの一部として組み込みました。標準出力には以下のように表示されます。
こちらのJSONログは Stackdriver Logging では検索可能になります
config tags で埋め込んだ request_id
で簡単にログフィルタが可能になります。(個人的にAWSの CloudWatch Logs よりも検索パラメータが直感的に分かりやすいので気に入っています)
2. Lograge
リクエストロギングには lograge を採用しています。同様に標準出力に切り替え、formatterの箇所でlograge用にカスタマイズを行います。
こちらは行数も長くなるのでファイルとして切り出します。http statusによってログレベルを分けています。
Googleコンソール上では以下のように転送されます。
3. Custom log
JSON出力してくれるlogger
を実装します。
logger
はブロック経由でログメッセージを渡すと、method 引数がprogname
としてログに埋め込まれます。JsonStdOutLogger
ではこのprogname
を Stackdriver Logging の検索用のキーとして利用しています。さらに params などの Hash をログとして渡す時には、そのまま検索可能なJSON payload 形式として merge させてます。
このような実装をlogger
に組み込むことで、Stackdriver Logging 上での検索性の高いロギングが完成します。一度コードが準備できれば同じインスタンスのロギングを必要箇所で使い回せばOKです。
Google Cloud Next ’18 in Tokyo
弊社CTOの中村が「GKE環境でのPCI-DSS準拠アーキテクチャ」という内容で Google Cloud Next ’18 Tokyo に登壇いたします。
ネクストカレンシーの仮想通貨販売所と、AnyPay の PCI-DSS 準拠アーキテクチャ紹介
9月 19日 水曜日 2:40–3:20 PM ザ・プリンス パークタワー東京 | Room 08AnyPay からは、クラウド × コンテナ技術である Google Kubernetes Engine(GKE) 環境にて、クレジットカード情報のセキュリティ基準である PCI-DSS に準拠した知見を紹介します。オンプレミスや非コンテナ環境とは異なるセキュリティのポイントや、低費用で PCI-DSS 準拠レベルのチェック体制を実現したアーキテクチャ・脆弱性スキャンやノードアップグレードの自動化等について説明します。https://cloud.withgoogle.com/next18/tokyo/sessions/session/223280
主にエンジニア向けの内容で、特に決済関連事業のドメインの方々には興味を持って頂ける内容と自負しております。また詳細はMedium記事として投稿いたしますので乞うご期待下さい。
We’re hiring!
モダンなインフラ環境に興味のある方、ブロックチェーンに興味がある方、テクノロジーの力で世の中を変えたい方、運用自動化が好きな方、DevOpsが好きな方。AnyPay社ではエンジニアを全職種絶賛採用中です。皆様のご応募お待ちしております。