📝

EKS上コンテナのRails consoleのログをCloudwatch logsに記録する

2023/12/02に公開

背景

エンタープライズ顧客向けにRailsで作ったアプリケーションの提案をしていますが、相手からいろいろな監査用のログを残すことが求められました。
これまでもちろんHTTPリクエストログは残せるようにしていましたが、rails cからデータを操作したりしたログも残した方が望ましいと思い残すようにしました。

Amazon EKS上で稼働するRailsアプリケーションのコンソール操作ログをAWS CloudWatch Logsに記録する手法を検討しました。

前提

  • RailsアプリケーションはEKS上で動いている
  • Rails.loggerのログはすでにfluent-bitでCloudWatch Logsに送られている

この前提に関する過去記事

https://qiita.com/k5trismegistus/items/9675d90a22746dd030cf

https://zenn.dev/k5trismegistus/articles/922715b2ad4e13

手順

  • fluent-bitでログを集約するためには、/proc/1/fd/1に書き込めばOK
  • Rails consoleで入力したコマンド履歴はReline::HISTORY.to_aを使用して取得可能。

production.rb(環境によって変えてください)に、以下を追記します。

production.rb
	if defined?(Rails::Console)
	  Rails.application.config.started_at = Time.current
	  at_exit do
	    Rails.logger.info({
	      title: "Rails console session started_at: #{Rails.application.config.started_at}",
	      history: Reline::HISTORY.to_a
	    })
	  end
	end

この設定により、at_exitのフックを使用して、セッション終了時にRailsのロガーを通じて操作ログをファイルに追記します。

補足

ただし、標準の設定では、.irb_historyに過去のセッションのコマンドも記録されてしまいます。これを避けるために、.irbrcで履歴の保存を行わない設定にします。

変更するファイル

.irbrc
IRB.conf[:SAVE_HISTORY] = nil

限界

この方法にはいくつかの限界があります。
もし、改善方法をご存知でしたらぜひコメントしてください!

exitで終了しないとログが残らない

exit!でセッションから抜け出した場合など、ログが記録されません。そのため、ログを確実に記録するには、exitコマンドの使用が必要です。

誰の操作かわからない

EKSではAWS IAMユーザーに対してKubernetesクラスタへのアクセス権限付与ができます。
どのIAMユーザーで、コンテナに接続しているのか、環境変数などで取れればどのIAMユーザーがコンソールをいじったのか追えるんですが。

アプリケーションのログしか取れない

これはRailsの設定をいじっている時点で当たり前なんですが、、。
監査ログとして十分にするにはコンテナ内rails console外で実行されるOSコマンドのロギングだったりも別途考慮する必要があります。
コンテナ内のシェルが、ユーザー入力も出力も全部自動で/proc/1/fd/1に書き込めるようにすれば全てのログが取れるんでしょうが、、。

Discussion