Kaigi on Rails 動画 (lograge の次を考える & Simplicity on Rails - RDB, REST and Ruby)

学習を進める上で、雑に書き出す場所が欲しいと感じ、はてなブログに書き出してみる。 自分は Rails が弱いので、Rails の学習をしていきたい。 ただ、Rails ガイドや学習書籍を観ていてもあまり頭に入ってこないような気がしており、Kaigi on Rails の動画を観るという学習手段を試してみたい。 正直、学習と言えるかは怪しいというか、少なくとも体系立った学習にはならないようには思う。 でも、やらないよりは良いだろう。 これがきっかけで、Rails ガイドなども読み進めやすくなるかもしれないし。

本題に入ろう。

logrageの次を考える — Ruby on Railsがデフォルトで出力するログの謎に迫る / Yutaka Kamei - YouTube

  • lograge
    • Rails の request ログを 1 行に集約してくれる
      • そもそも Rails のログで request ログを吐いているのすら知らなかった
    • 使ったことがない
    • 複数の Formatter をサポートしており、JSON も含む
    • Datadog も lograge を推薦している
      • 今もそうなのか簡単に調べてみたところ、そうっぽい

ここで lograge リポジトリの README を読んでみる(偉い)。 なお、DeepL の拡張機能で翻訳したもので読む。 自分は英語がまあまあ得意なので、英語で読みたくなるが、表意文字である日本語の方が早いので、ここからしばらくは積極的に DeepL を使っていきたい。shift + command + Y。

Logrageは、Railsのノイズが多くて使いづらく、解析不能で、複数のプロセスやサーバを実行している状況では読めないデフォルトのログ出力に正気をもたらそうとする試みです。

表現に笑う。

すべてをログに記録するRailsのデフォルトのアプローチは、開発時には素晴らしいのですが、本番で運用するときには最悪です。Railsのログはほとんど役に立たなくなります。

なるほど、開発時には良いけど、本番で迷惑なのか。

↓ これが、

Started GET "/" for 127.0.0.1 at 2012-03-10 14:28:14 +0100
Processing by HomeController#index as HTML
  Rendered text template within layouts/application (0.0ms)
  Rendered layouts/_assets.html.erb (2.0ms)
  Rendered layouts/_top.html.erb (2.6ms)
  Rendered layouts/_about.html.erb (0.3ms)
  Rendered layouts/_google_analytics.html.erb (0.4ms)
Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)

↓ こうなる、とのこと

method=GET path=/ format=json controller=HomeController action=index status=200 duration=79.0 view=78.8 db=0.0

そもそもログを見たことがなかったので「へえ、こうなった方が本番ではありがたいんだ」という感じ。 何でもログに吐いてくれた方がありがたそうな気もするけど。 まあ、確かに、lograge の出力の方がシンプルで、読む気は起こる。 省略されている情報としては、全部を書き出すつもりはないけれど、

  • 127.0.0.1
    • IP アドレス。なお『IP アドレス』という単語が咄嗟に出てこなかった、よろしくない。

ここで、脱線して、IP アドレスについて少し調べてみる。 42 Tokyo で勉強したし、応用情報技術者の資格を取得した時も学んだはずなのだけど、頭から抜けてしまっている。

まず、127.0.0.1 という IP アドレスは、localhost というホスト名に対応している。 localhost は触れる機会があるけれども、これを『ホスト名』と呼ぶのは知らなかった。 なお、127.0.0.1 は、コンピュータが自分自身を指すために仕様する特別な IP とのこと。 感覚では理解できていても、このように言語化することはできていなかった。 この目的の IP を『ループバックアドレス』といい、127.0.0.1 のみでなく、127.0.0.0 から 127.255.255.255 までの全てのものを含む。 この範囲は 127.0.0.0/8 と表記できる。 この表記の方法を CIDR (= Classless Inter-Domain Routing) 方式という。 この /8 は、アドレスの最初の 8 ビットがネットワーク部であることを示している。 この場合、ネットワーク部でない残りの 24 ビットは、ホスト部という。 "Classless" という名前については、以前は A, B, C クラスという分け方をしており、その方法で IP アドレスの割り当てに無駄が生じて方式が変更されたことに由来する。"Inter-Domain Routing" については、そのままであるが、ドメイン、つまりネットワークをまたいでのルーティング、とのこと。 また、ホスト名と IP アドレスの結びつきは、DNS が管理している。 また、localhost:30003000 の部分は、ポート番号。 ポート番号は、上限は 65535。また、0 から 1023 までは、ウェルノウンポートであり、予め割り当てられている。 例えば、HTTP は 80、HTTPS は 443。 なお、HTTP や HTTPS は、通信プロトコルという。 これらの通信プロトコルを用いると、ポートへのルーティングは、ブラウザが勝手にやってくれる。 つまり、http://www.example.com へのアクセスは http://www.example.com:80 へのアクセスと同じ。

また、パブリックアドレスとプライベートアドレスというものが存在する。 以下、プライベートアドレスの範囲。

10.0.0.0 から 10.255.255.255 (10.0.0.0/8)
172.16.0.0 から 172.31.255.255 (172.16.0.0/12)
192.168.0.0 から 192.168.255.255 (192.168.0.0/16)

閑話休題。← 生まれて初めて使った気がする

Lograge の基本戦略

Rails が出力する Request 関連のログを無効にする。

  • Request 関連の LogSubscriber が subscribe しているイベントを unsubscribe
    • LogSubscriber というものがあるのか
  • Rails::Rack::Logger をモンキーパッチ
    • こんなものが存在し、動いているのか。

自前の LogSubscriber を attach し、ログ出力

LogSubscriber とは

ActiveSupport::Notifications のイベントを subscribe しログ出力する

Rails のコアの実装ごとに用意されている

rails new で出るログはほぼこれらによる

残りも見た。 middleware を swap できることを知った。 そもそも middleware をあまり知らないのだけれども。

Simplicity on Rails - RDB, REST and Ruby / MOROHASHI Kyosuke - Kaigi on Rails 2023 - YouTube

某氏が今回の全セッションで一番オススメできると仰っていたもの。 初心者にもオススメとのこと。 ご本人とも挨拶だけさせていただき、優しい方でいらっしゃった。 「これから何回も見るだろう」という X でのポストも目にした。 SMS さんにご勤務で、しおいさんやしんくうさんも同僚とのこと。 SMS、存じなかった、、、あれ、もしや、某氏が行きたかった会社かな?

『シンプル』について、「やはり scaffold がヒントになる」と仰っていて、意外な感じ。 自分は、scaffold を舐めてきてしまったのだと思う。 初心者が使う機能、といった偏見で。 正されて良かった。 また、「DB のテーブル構造と、画面の構造、特に入力単位を合わせる」というのも、自分が意識していなかったことで、勉強になる。 と言っても、あまり具体的なイメージが湧いているわけではないのだけど。

DB 設計におけるイベントエンティティを見出す

タイトルを読んでもピンと来ないので、自分が弱い部分なのだと分かる。

  • ドメインに現れるイベントエンティティを見出す
  • それを ActiveRecordhas_many :through アソシエーションで指定するエンティティにする

とのこと。

イベントエンティティとは? → DB 設計の考え方で、エンティティとは、平たく言うとテーブルのこと。 それは、二種類に分類される。すなわち、リソースエンティティと、イベントエンティティ。 「もの」か「こと」か。分かりやすい! イベントエンティティは、名前を持たない。なぜなら、イベント自体がその行為の名前になっているため。

例えば、Kaigi のリソースエンティティを考えると、カンファレンスも種類があり、また人々も複数のカンファレンスに参加できるので、多対多の関係。 RDB では、多対多を表現する際、両者を参照するエンティティを導入する。 これを、リレーションシップモデルと言う。

このリレーションシップモデル自体に意味を持たせて扱う場合は、has_many :through リレーションシップを設定する。これは、中間に join モデルを使うもの。

  • join モデルって何だ

それに対し、リレーションシップモデルで何も特別なことをする必要がない場合は、has_and_belongs_to_many リレーションシップを使う。こちらは、join モデルが不要。通常「ハビタム」/ habtm。ほえ〜。 しかし、この「リレーションシップモデルで何も特別なことをする必要がない場合」というのはごく少数であり、モロさんはここ数年、habtm を全く使っていらっしゃらないとのこと。

Rails の気持ちになって考える」というスライド名、おもしろいし、すごい。 当初は habtm 関連しか存在しなかったが、2 で has_many: through が追加され、その後、through 族が隆盛を極めており、そちらの方がドメインの表現として優れているとのこと。 機能としても、through の through などで関連を辿れるのが超便利、とのこと。

イベントエンティティを「見出す」という表現にポイントがあるみたい。存在が自明なリソースエンティティと異なり、慣れないと発見しづらい、とのこと。 また、実世界のサービスでは、このイベントエンティティができることが、重要なコンベージョンポイントになっていることが多い、とのこと。 例えば、先ほどの Kaigi サービスについて考えると、各カンファレンスとユーザーが単に多対多なのではなく、「登録」している関係があるのだ、と判明する。