Share
Embed
Transcript
50 slides
-
⾃⼰紹介 ⾃⼰紹介 2 株式会社プレックスの Plex Job(HR プラットフォーム)チームでSWEとしてサービス の開発と運用を担当しています。 種井 覚道
(Tanei Akimichi) GitHub: @kakudou3 X: @kakudooo -
ログの分類 7 ログについて整理 非構造化ログ 構造化ログ 概要 各フィールドについて、key,value で明確に マッピングされていないもの 各フィールドについて、key,value
で明確に マッピングされているもの(例: json) 特徴 ⼈間が解釈しやすい形式 機械が解釈しやすい形式 例 -
ログの⽤途 ログについて整理 8 参考: Webアプリケーションのログに関するいくつかの考察 用途 説明 監視 システム障害やパフォーマンスの低下が発生したときに気付ける 調査
エラーやパフォーマンス低下の原因特定、不具合時の影響範囲がわかる 分析 未知の情報を探索したい 監査 法務観点などから保存することが定められている -
アプリケーションの構成 • 求⼈サイト/採⽤管理ツール (ATS)はじめ、社内の⼈材マッ チングの効率化ツールなど複数 のプロダクトやシステムを開発 ‧運⽤ • モノリシックなWebアプリケー ションであり、いずれも
Rails(APIモード)が使われてい る 私たちのログ活⽤ 10 -
信頼性がより求められるフェーズに 私たちのログ活⽤ 11 成⻑による変化 (⼩規模 → 中規模) 課題 • サービスの利⽤者数の増加
◦ 社内外のユーザー • システムの複雑化 ◦ 社内外の複数システムとの連携 ◦ 取り扱うドメインの拡⼤ • 開発に関わるメンバーの増加 ◦ 開発メンバー ◦ ステークホルダー • 不具合発⽣時の損失が⼤きい ◦ アプリケーションで発⽣した重要な イベントを素早く検知したい • 調査‧事後対応など運⽤コスト が増加 ◦ 原因の特定や復旧までの時間をなる べく短縮したい ◦ 作業の効率化や属⼈化の防⽌ -
信頼性がより求められるフェーズに 私たちのログ活⽤ 12 成⻑による変化 課題 • サービスの利⽤者数の増加 ◦ 社内外のユーザー •
システムの複雑化 ◦ 社内外の複数システムとの連携 ◦ 取り扱う職種領域の拡⼤ • 不具合発⽣時の損失が⼤きい ◦ 社内外のユーザー • 調査‧事後対応など運⽤コスト が増加 ◦ 社内外の複数システムとの連携 ◦ 取り扱う職種領域の拡⼤ SRE Engagement Model 👉 仕様やトラフィックが複雑化するアプリケーションの状態を ”網羅的かつ詳細”に把握することが重要になってくる 引用: SRE Engagement Model システムの複雑性と 信頼性への要求が同時に ⾼まるフェーズ -
アプリケーションの監視と調査にログを活⽤する 私たちのログ活⽤ 14 参考: Webアプリケーションのログに関するいくつかの考察 用途 説明 監視 システム障害やパフォーマンスの低下が発生したときに気付ける 調査
エラーやパフォーマンス低下の原因特定、不具合時の影響範囲がわかる 分析 未知の情報を探索したい 監査 法務観点などから保存することが定められている -
当時のアプリケーション監視 私たちのログ活⽤ 15 • すでにDatadogが使われていた • メトリクス、トレース、ログな どは収集されており、⼀部の機 能は活⽤できていた •
ログがツールから正しく認識さ れておらず、活⽤は限定的 ◦ 調査時は全⽂検索 ◦ ログがリクエスト(処理)の単位で グルーピングされていない ログ Error Traking (エラー検知) APM (パフォーマンス監 視) Log Explore (ログ検索) 調査 調査 -
監視ツールとログ 私たちのログ活⽤ 16 👉 監視ツールは構造化ログを取り込むことで、ログを対象とした 便利な機能が有効化される • ログに関連する機能の例 ◦ ログ検索
◦ アラート ◦ Error Tracking (エラー検知) ◦ トレース とログの関連付け -
ログが信頼性を⾼めるための武器になっていない 私たちのログ活⽤ 17 ⾮構造化 ログ Error Traking (エラー検知) APM (パフォーマンス
監視) Log Explore (ログ検索) 調査 調査 ⾮構造化ログがゆえに 監視ツールの機能を活⽤しきれていない -
ログの活⽤に向けてすべきこと 1. アプリケーションを構成する各プロセスで構造化ログ が出⼒されている 2. 構造化ログをツールに合わせてフォーマットする 私たちのログ活⽤ 19 API Worker
Cron Job 構造化 フォーマット ログ ログ ログ -
構造化対象のログ Railsアプリケーションのログを構造化する 21 • アプリケーションコードからのRails.loggerの呼び出し ◦ 例: Rails.logger.info(...), Rails.logger.error(...) •
内部フレームワークのイベントログ ◦ API: Rack, ActionController, ... ◦ Worker: ActiveJob, ActionMailer, ... ◦ Cron: Rake, ... ◦ 共通: ActiveRecord, 例外, ... 例 -
Rails.loggerを拡張する Railsアプリケーションのログを構造化する 22 • Formatterの作成 ◦ ログのJSON⽂字列化 • Rails.loggerの拡張 ◦
info,errorメソッドの引数をHashなどのデータ型に対応させる • タグ付け ◦ スレッドローカルなタグストレージの実装 • 内部フレームワークのイベントログを構造化 ◦ ActiveSupport::LogSubscriberの拡張 ◦ ミドルウェアの拡張 アプリケーションコード からのRails.loggerの 呼び出し 内部フレームワークの イベントログ -
Rails.loggerを拡張する Railsアプリケーションのログを構造化する 23 • Formatterの作成 ◦ ログのJSON⽂字列化 • Rails.loggerの拡張 ◦
info,errorメソッドの引数をHashなどのデータ型に対応させる • タグ付け ◦ スレッドローカルなタグストレージの実装 • 内部フレームワークのイベントログを構造化 ◦ ActiveSupport::LogSubscriberの拡張 ◦ ミドルウェアの拡張 アプリケーションコード からのRails.loggerの 呼び出し 内部フレームワークの イベントログ 標準インターフェースの上書きや、⼀部の ログ出⼒の抑制 LogSubscriberの置き換えやモンキー パッチが必要になることも、Railsの内部 APIへの依存度が⾼くなってしまう スレッド内でタグ情報を管理する仕組み の実装 -
Rails.loggerを拡張する Railsアプリケーションのログを構造化する 24 • Formatterの作成 ◦ ログのJSON⽂字列化 • Rails.loggerの拡張 ◦
info,errorメソッドの引数をHashなどのデータ型に対応させる • タグ付け ◦ スレッドローカルなタグストレージの実装 • 内部フレームワークのイベントログを構造化 ◦ ActiveSupport::LogSubscriberの拡張 ◦ ミドルウェアの拡張 アプリケーションコード からのRails.loggerの 呼び出し 内部フレームワークの イベントログ 標準インターフェースの上書きや、⼀部の ログ出⼒の抑制 LogSubscriberの置き換えやモンキー パッチが必要になることも、Railsの内部 APIへの依存度が⾼くなってしまう スレッド内でタグ情報を管理する仕組み の実装 実装や保守のコストは⾼い -
gemの活⽤ Railsアプリケーションのログを構造化する 25 Lograge Rails Semantic Logger 概要 リクエストログを1⾏にまとめるため のgem、構造化にも対応
Rails全体のイベントを構造化するためのgem メンテナンスの 継続性 やや⼼配 (最後のリリースは2023年) 直近まで⾏われている (2025年中にリリースあり) 構造化対象の ログイベントの 網羅性 ActionViewやActionControllerな ど、リクエスト→レスポンスまでの ログイベントが対象 ActionController,ActiveJob,ActiveRecord などの各内部フレームワークの ログイベントが対象 -
私たちはどうしたか? Railsアプリケーションのログを構造化する 26 • ActionController • ActionMailer • ActionView •
ActiveJob • ActiveRecord • Rack • Sidekiq • ActionDispatch • ActiveSupport • … • gemの活⽤ (Rails Semantic Logger) ◦ 実装‧維持コスト (リソースが限られるため、なるべ く出来合いのものがあれば使いたい) • メンテナンスの継続性 ◦ 基盤にあたる部分のため、RailsのAPIの変更に 追従する必要があることも • 構造化対象のログイベントの網羅性 ◦ ⾃分たちでメンテナンスが必要なコードを 少なくしたい -
⼀部に漏れがあった... Railsアプリケーションのログを構造化する 28 • 定期バッチ(Cron Job)を Rakeタスクで実装している • 運⽤をはじめてみたところ例外時 (unhandledな)に出⼒されるエラー
ログが構造化されていなかった 👉 Rakeタスクから出⼒されるエラーログも構造化の対象にした い API Worker Cron Job (Rakeタスク -
Rakeタスクのエラーログが構造化されていない② Railsアプリケーションのログを構造化する 30 • 該当箇所のコード • RakeタスクはRailsコマンドで実⾏ することが可能だが、例外処理に ついてはRailsのエコシステムで実 ⾏されるわけではない
• 例外については独⾃の機能traceメ ソッドでエラーログが出⼒される -
Rakeタスクのエラーログを構造化する • begin ... rescue ... end でtask内で発⽣した例外を補⾜する • at_exit
ブロックを定義する • Rake にパッチをあてる Railsアプリケーションのログを構造化する 31 検討: 3つの⽅法 -
begin ... rescue ... end で対象の処理を囲う • 例外が発⽣した場合は、 Rails.logger でログを出⼒する
• シンプルで理解しやすいが、実装 漏れを防ぐのが難しい 32 Railsアプリケーションのログを構造化する -
at_exit ブロックを定義する • at_exit ブロックを定義して、ラン タイムの終了時に呼び出される処 理を登録する • sentry をはじめとした監視ツール
の SDK もエラートラッキングのた めに at_exit を使⽤して例外を捕捉 してログを収集していたりする • 導⼊が簡単で⼀度定義するだけで よいが、登録と呼び出しの順番を はじめとした副作⽤に注意する必 要がある 33 Railsアプリケーションのログを構造化する -
Rakeにモンキーパッチをあてる • lib/rake/application.rbを参照 • display_error_messageメソッド にモンキーパッチをあてる • モンキーパッチの対象や影響範囲 が限定的であることから、今回は この⽅法を採⽤
34 Railsアプリケーションのログを構造化する 参考: Rake タスクの Unhandled Exception を Rails.logger でログ出力する方法 -
整理 Railsアプリケーションのログを構造化する 36 • Rails Semantic Loggerで構造化対象 (API, Worker Cron
Jobのプロセス)の⼤部分を網羅 ◦ Rails.logger ◦ 各内部フレームワーク • それでも不⾜しているものを補う ◦ Rakeタスク -
ログをフォーマットするタイミング • ログのフォーマットをアプリケーション側で⾏うか?、ツール側で⾏うか? についても検討が必要となる • SWEを中⼼としたチームであることから、ログのフォーマットに関する設定 はアプリケーションに集約することに ◦ 具体的な実装については、弊社ブログを参照ください 構造化ログをツールに合わせてフォーマットする
39 Formatter? Remapper? Error Tracking ログ ログ -
ログの活⽤に向けてやるべきこと 構造化ログをツールに合わせてフォーマットする 40 ✅ アプリケーションを構成する各プロセスで構造化ログが 出⼒されている ✅ ツールに合わせてログをフォーマットする API Worker
Cron Job 構造化 フォーマット ログ ログ ログ -
「監視」や「調査」⽤途のログ活⽤が進んだ ログを構造化した結果 42 構造化 ログ Error Traking (エラー検知) APM (パフォーマンス
監視) Log Explore (ログ検索) 調査 調査 アラート 異常検知 (監視) -
ログを構造化した結果 43 • 監視: アプリケーションの重要イベントの捕捉 ◦ エラー検知および集計の⾃動化 ◦ アラートへの応⽤ •
調査: ツールを通じた調査業務の⺠主化 ◦ ログの検索性が向上 ▪ フィルターや集計の効率化、正規表現による前処理などが不要に ◦ ログとトレースの紐づけの⾃動化 ▪ トレースと紐づけることで、ログをリクエスト単位にまとめることができる ▪ 問題のあるリクエストの詳細情報をログから得ることができる -
Railsへの期待 45 • Rails 8.1で構造化ロギングを サポート ◦ Structured Event Reporting
◦ Structured event subscribers • 構造化ロギングの標準化が進む ◦ これまでgemや独⾃の解決⽅法で 対応してきた部分 • 構想 ◦ Adrianna Chang - From Chaos to Clarity: Structured Event Reporting in Rails 構造化ロギングのサポート Add structured logging next to developer logging -
Rakeとエラーレポートティングのサポート Railsへの期待 46 • Rakeタスクでバッチ処理や運⽤ 上のスクリプトを実装している ことも多いはず • 例外時(unhandledな)に Rails.loggerやエラーレポー
ティングAPIが呼び出されるよう にできないか • discussion -
まとめ • 構造化ロギングのススメ ◦ ログの構造化は⾒逃されがちだが、信頼性の向上においてコストパフォーマンスのよい打ち ⼿となる ◦ ツールをはじめとして機械的な後⼯程が少しでも考えられるのであればフェーズに関わらず 基本的には対応しておくとよい •
Railsアプリケーションのログの構造化にあたっては、いくつか課題があり、 状況に合わた技術選定を⾏う必要がある ◦ 構造化対象のログの網羅、ツールの仕様に合わせたフォーマット ◦ システムやチームの規模などを前提とした設計 • Rails 8.1以降で構造化ロギングの機能が組み込まれる予定 ◦ これから構造化に取り組む場合は動向を確認しながら進めることを推奨 まとめ 47 -
Appendix ① Appendix 49 • ⼊⾨ 監視 • Webアプリケーションのログに関するい くつかの考察
• SRE Engagement Model • Lograge • rails_semantic_logger • Railsアプリケーションのログを構造化し てDatadogで活⽤するまで • Semantic LoggerのログをDatadog⽤にカ スタマイズしてみた • Rake タスクの Unhandled Exception を Rails.logger でログ出⼒する⽅法 • Add structured logging next to developer logging • Structured Event Reporting • Adrianna Chang - From Chaos to Clarity: Structured Event Reporting in Rails -
Appendix ② Appendix 50 • ログ収集にあたっての注意点 ◦ コスト ▪ 収集対象の取捨選択、収集したログの保存期間の検討
◦ セキュリティ ▪ 秘匿情報は必ずマスキングする ▪ Prevent logging sensitive information in Rails, and beyond • 構造化ログについての補⾜ ◦ ⾮構造化ログと⽐較して、ログのデータサイズが多くなってしまうこともある ◦ Understanding Structured Logging: A Comprehensive Guide