Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Reasonable logging in BtoB Application
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
hoshino tsuyoshi
October 10, 2024
Technology
150
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reasonable logging in BtoB Application
テーマ: 変更履歴を適切に保持したい
rails ruby
hoshino tsuyoshi
October 10, 2024
More Decks by hoshino tsuyoshi
See All by hoshino tsuyoshi
GitHub Actionsで `shell` に `ruby {0}` と書ける話
hoshinotsuyoshi
2
200
RDSのパスワードローテーションについて考えてみた話
hoshinotsuyoshi
1
140
「技術的負債」について私から言えること私から言えないこと
hoshinotsuyoshi
2
1.2k
spreeのrails updateの戦いの歴史と github上のPR作成時の工夫
hoshinotsuyoshi
0
1.2k
Ruby is fun but difficult
hoshinotsuyoshi
0
440
バッチ処理でhakoを使う話
hoshinotsuyoshi
0
9.9k
docker swarm 触ってみた #dockerlt
hoshinotsuyoshi
0
1.2k
貧者のためのCoreOS(Jenkinsを例に)
hoshinotsuyoshi
1
1.6k
個人で使ってみた Docker と CoreOSとか
hoshinotsuyoshi
7
3.7k
Other Decks in Technology
See All in Technology
PQC移行の今 -- IETF からみた現在地
satokan
4
500
Oracle Cloud Infrastructure(OCI):Onboarding Session(はじめてのOCI/Oracle Supportご利⽤ガイド)
oracle4engineer
PRO
3
21k
Apache Iceberg が拓く AI 時代のオープンレイクハウス
tomtanaka
0
110
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
630
DORA_Metrics.pdf
wagnerfusca
1
110
猫でもわかるKiro Web
kentapapa
1
120
Coil3を内部実装から読み解く~キャッシュ戦略とAVIF画像の描画〜/nikkei-tech-talk50
nikkei_engineer_recruiting
0
110
セルフサービスのオブザーバビリティ基盤をOpenTelemetryで作る / Building a Self-Service Observability Platform with OpenTelemetry
ymotongpoo
3
390
Making AI Agents Safe and Fast- Jev, Obsidian, and the Meta-Harness
x5gtrn
PRO
0
150
AIに書かせて、プラットフォームで縛る ― EKSプラットフォームで実践した責任境界と権限設計
elmodev09
0
830
「大丈夫そう?」をObservabilityで確かめる
mrmtsu
0
200
Harness Engineering on Rails
joelq
0
660
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
331
22k
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
540
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Everyday Curiosity
cassininazir
0
330
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
350
Designing Experiences People Love
moore
143
24k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
How to train your dragon (web standard)
notwaldorf
97
6.8k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Transcript
Roppongi.rb #23 "Proposals on Rails 2024" Reasonable logging in BtoB
Application ROUTE06, Inc. GitHub:@hoshinotsuyoshi 1
Me GitHub:@hoshinotsuyoshi • X:@hoppiestar • • SWE in ROUTE06 •
EDI platform 2023- • NO-CODE platform for building business apps 2024- • Yes, API backend is made with Ruby on Rails • public repo?(TBD) • 2
Outline EDI Platform • テーマ : 変更履歴を適切に保持したい • PaperTrail gemの手法とイベントソーシングについて説明
• 「誰が変更したか」を記録する工夫 • その他の工夫 • まとめ • 3
4
商取引におけるさまざまな事柄 (注文、商品、見積、出荷、承認、 etc.) を扱う。 EDI platform BtoB Applicatoin • many
resource classes • • buying, ordering, shipping ... • many stakeholders • • buyer, supplier, trader ... • ... • 5
テーマ : 変更履歴を適切に保持したい 6
商取引におけるさまざまな事柄について、 「誰が、いつ、どのように変更を加えたか」 を保持したい 目的 ... (今回は分析用途の目的は薄い ) テーマ : 変更履歴を適切に保持したい
システム不具合や障害発生時の調査・分析 • SOC監査対応 • リソースの変更履歴を表示するビューの追加実装 • 7
変更履歴 -> アプリケーションのログに頼る ?? 「アプリケーションのログにモデルの変更を記録する」という手もあるかもしれな いが ... • このログには他の情報も記録しているため、それらが混ざった状態で一定期間保持 する必要がある
• CloudWatchLogsのデータ保持のための料金もかかる • (or Logを分ける ?) • 8
paper_trail gemは、 Railsアプリケーションでモデルの変更履歴を追跡・管理する ための仕組みを提供する。 各モデルの変更を追跡し、 versions テーブルに履歴として保存する。 以下のコマンドを実行し、 versions テーブルを準備する
bundle exec rails generate paper_trail:install [--with-changes] [--uuid] bundle exec rails db:migrate 手法 : paper_trail gem 9
class Article < ApplicationRecord has_paper_trail end 手法 : paper_trail gem
1. バージョンの作成について モデルにバージョン管理を追加 : モデルに has_paper_trail を追加するだけで、そ のモデルの Create/Update/Destroy操作が自動的に追跡される。 • versions テーブルに履歴を保存 : 各変更は versions テーブルに保存され、バージ ョンごとの変更内容が記録される。 • 10
2. バージョンの保持内容について versions テーブルには、以下の情報が含まれる : | id | item_type |
item_id | event | object | ... |-----|-----------|---------|--------|------------------------------------------------------------------------------------| | 1 | Article | 1 | create | null | | 2 | Article | 1 | update | {"title": "First Post", "content": "Hello World!", "author": "Alice"} | | 3 | Article | 1 | update | {"title": "First Post - Revised", "content": "Final revision.", "author": "Alice"} | 手法 : paper_trail gem item_type: 追跡対象モデルのクラス名 (polymorphic) • item_id: 追跡対象モデルの ID(polymorphic) • event: 作成、更新、削除のイベント名 • object: 変更前のオブジェクトの状態を JSON形式 (または YAML)で保存 • object_changes: 各カラムがどのように変わったかを記録 • 11
イベントソーシングは、システム内で発生したすべてのイベントを保存し、そのイベ ントからデータの現在の状態を導き出す手法。 eventが主役となり、データの変化を イベントとして記録する。 1. eventsテーブルでのデータ管理 | aggregate_id | seq
| event_type | event_data |... |--------------|-----|-----------------|----------------------------------------| | Article:1 | 1 | ArticleCreated | {"title": "First Post", "author": "A"} | | Article:1 | 2 | ArticleUpdated | {"content": "New content"} | 参考 : イベントソーシング イベントを events テーブルに記録。 • 各イベントが「いつ、何を変更したか、何が起きたか」という情報を持つ。 • 12
2. Single Source of Truth 3. Projectionで状態を復元 参考 : イベントソーシング
イベントがデータの唯一の信頼できる情報源( Single Source of Truth) 。 • 過去の状態は、イベントの履歴を projection(投影)して再構築することで確認可 能。 • events テーブルのデータを集計・投影することで、アプリケーションで使用する 現在の状態を表現。 • この手法により、過去の任意の時点のデータ状態を再現することが可能。 • 13
イベントソーシング ActiveRecordのコールバックでバージョンを作成する手法 ざっくりまとめると イベントが主役 • gem例 : rails_event_store • リソースが主役
• gem例 : paper_trail • gem例 : audited • 14
1. ActiveRecordとのスムーズな統合 モデルの変更があれば自動的にバージョンが作成され、余分な設定や複雑なロジ ックを書く必要がない。 2. コールバックを活用した直感的な動作 ActiveRecordのコールバックを活用し、 save や update
メソッドの操作時に履 歴が自動で保存される。 Rails標準のメソッドを使うだけで、 paper_trail が自 動的に動作するため、開発中にイベント処理やトランザクションの管理をあまり 気にせずに済む。 paper_trail を採用したモチベーション 15
「誰が変更したか」を記録する工夫 16
「誰が変更したか」を記録する工夫 whodunnit (who done it・誰がやったか ?) の活用 • IPアドレス? •
できれば DBに保存したくない ... • アプリケーションのログに吐く ? • 17
平たく言えば、ユーザー IDを version テーブルの whodunnit カラムとして追加す る。コントローラに設定が必要。 class GraphqlController <
ApplicationController # ... before_action :set_paper_trail_whodunnit # ... whodunnit の活用 次のように書くと、コントローラーで current_user が定義されている場合、 current_user.id が whodunnit 列に保存される (という規約 )。 • current_user は devise gemを使っていてユーザークラスが User の場合に利用 されるメソッド。 • 18
devise を使っていない場合は current_user を定義したりすれば OK。 def current_user # 別途rack middlewareでセットしたユーザーを取得
request.env["xxx.tenant_user"] || raise end whodunnit の活用 19
IPアドレス IPアドレス ? 調査ケースによっては、あると便利な場合がある • 機微情報という見方もできる。できればあまり直接 DBに保存したくない ? • アプリケーションのログに吐く
? • --> AWSのログに頼るのはどうか • 20
--> この IDを追加で versionsテーブルに記録すれば OKでは? IPアドレス 今回の AWSの構成の事情 CloudFrontが ALBや
Railsアプリケーションの前段に配置されている • S3にログを吐く設定にしているので、ソース IPアドレスとリクエストを識別でき る ID( X-AMZ-CF-ID )が残っている • 21
paper_trail の 機能を使う。 例えばコントローラーに以下のように書けば、 x_amz_cf_id を versionsテーブルに記 録できる。 def info_for_paper_trail
{ # CloudFront. "x_amz_cf_id" => request.headers["HTTP_X_AMZ_CF_ID"], } end これで versionsテーブル -> X-AMZ-CF-ID -> S3のログから IPアドレスをたどることが できるようになった ! IPアドレス 22
さらに追加で Amazon X-Rayとアプリケーションログとの紐付け用に情報を足す例 def info_for_paper_trail { # CloudFront. "x_amz_cf_id" =>
request.headers["HTTP_X_AMZ_CF_ID"], # 追加: アプリケーションログと紐づけられるRequestID "request_id" => request.request_id, # 追加: Amazon X-Ray. ALBのログと紐づけられるID. "x_amzn_trace_id" => request.headers["HTTP_X_AMZN_TRACE_ID"], } end 参考 23
これで ...リーズナブルに対応できたのでは ? (分析対応ではなく )障害調査・侵害疑惑調査・監査対応などを目的と想定する場合 はこれで十分 • アプリケーションログ (ECS/CloudWatchLogsを利用 )も肥大化しないしリーズナブル
• CloudFrontのログは S3に置かれるので、 Amazon Athenaによる検索が可能 • 積極的に活用はしていないが、仕組み自体は準備済みであり、 CloudWatchで検索 をかけるよりも金銭コストが低いと思われる • 24
ここまでで 変更履歴が記録できるようになった 何を • いつ • 誰が • AWSのログと組み合わせることで「誰がどこから」もトレース可能に •
25
その他の工夫 26
保存時に必ずコールバックを発火するようにしたい コールバックが発火しないと versionが保存されないので ... update_column(s) , update_all , insert ,
... • -> rubocopの設定で禁止 • Rails/SkipsModelValidations • 27
1つのテーブルが極端にレコード数が増えるのを防ぐため、 クラスごとに versionsテーブルを分割。 # バージョンテーブルの抽象クラス class TenantRecordVersion < TenantRecord self.abstract_class
= true class << self def inherited(subclass) super # ...snip... # PostgresのRLSのための設定をここに書く(今回は説明省略) # ...snip... subclass.include ::PaperTrail::VersionConcern versions テーブルが肥大化することを抑止 28
このように使う : # ActiveRecordのクラス class Image < TenantRecord has_paper_trail versions:
{ class_name: "ImageVersion" } # ...snip... # Imageクラス用のバージョンテーブル class ImageVersion < TenantRecordVersion end versions テーブルが肥大化することを抑止 29
まとめ 30
変更履歴の保持手法について、 paper_trail gemを中心に説明しました。 この手法により、 BtoBアプリケーションにおけるログの管理がより効果的に行える ようになったと考えています。 まとめ 簡便さを重視し、 Railsエンジニアのマインドセットに適した履歴管理を実現 •
ActiveRecordとのスムーズな統合やコールバックを活用することで、エンジニアの 負担を軽減 • whodunnit や CloudFrontログの活用により、誰がどこから変更したかの追跡が可 能に。直感的かつリーズナブルな履歴管理が実現 • 31
「うちはこんな設計にしてる」 「こうしたほうがいいぞ !」みたいな話も聞きたいです ! 質問があれば、いつでもどうぞ! みなさんはどうやっていますか? 32
東京でお会いしましょう ! 👋 さいごに宣伝 33