この記事は、Elixir Advent Calendar 2020 の1日目です。
アルケミストのみなさんこんにちは。こんにちは。今年もアドベントカレンダーがはじまりました。去年は派手なネタに力を入れて書いたのですが、今年は地味〜に軽く行きますね。
Elixir の Logger の問題
今回のネタは前から気になっていた Elixir の Logger の話です。ずっとブチブチ文句を言ってたのですがついに version 1.11 で改善されました。何が気に食わなかったかと言うと、これまでのElixir ではレベルが4つに限定されているからなのでした。
- :debug - デバッグ関連メッセージ
- :info - いろんな情報提供
- :warn - 警告
- :error - エラー
これはただでも種類が少ない上に MacOS での開発でもっと困る事態を引き起こしてました。Logger の出力を syslog に向けることができるのですが、Macの「コンソール」アプリには error と warn しか出てこないので(手元のはMacOS10.15.7)、事実上ログレベルを2種類に制限されてしまうという状況を招いていました。このため debug や info レベルのログメッセージを warn や error として Logger に出すというあまり良くない振る舞いを強制されることになってました。
Logger レベルの改善
ちょっとまえに Erlang の logger が先に改善されて Elixir も追いかけるように改善されました。今は以下の8つのレベルになっています。これによると重篤なレベルから以下のように定義されています。
- :emergency - システムが利用不能・パニック状態になった場合
- :alert - 警報、直ちに措置が必要な場合、例えばデータベースの障害など
- :critical - 致命的な状況
- :error - エラーの発生
- :warning - 警告
- :notice - 通常のただし重要なメッセージ
- :info - いろんな情報
- :debug - デバッグ関係のメッセージ
これでレベルの少なさに悩む必要はなくなりました。MacOS のコンソールアプリでも6レベルが出せますので、info や debug レベルのメッセージを notice レベルとしてログ出力しないとならないとしても、まあ許せる範囲でしょう。
なお、「致命的な状況」「エラーの発生」「警告」ってなんだよ〜、説明になってないぞ、と憤慨される向きもあろうかと思いますが、これは Elixir が悪いのではなく元々このレベルを規定している IETF の syslog の標準ドキュメント RFC5424: The Syslog Protocol にそう書いてあるのです。
そのほかの改善
今回の Logger ではメッセージとして出力できるのが(引数として許す型が)文字列以外にもリストやマップを受け取れるようになりました。例えばこれまでは、
err_info = [something: :reported, this: :error]
を Logger に出力させたければ
Logger.error(inspect(afo))
と書いていたのが
Logger.alert(afo)
とか直接書けるようになりました。これは便利です。
ただしこれ、もう一声感があって、もうすこし複雑な構造は使えません。たとえば Logger に出したくなるのはプロセス作ったときの pid だったり何かオープンした結果の ref だったりするのですが、それは直接書くことができず、あいかわらず inspect/1
関数に食わせて文字列にしないとなりません。
まとめ
Logger の機能が良くなって使いやすくなりました。さらによく使う型にも対応してくれると嬉しいですね。自分で改良して本家にプルリク出したいところです(夢)。
さて、明日のElixir Advent Calendar 2020 2日目の記事は @Papillon6814 さんのTimexで時を操るです。お楽しみに!