Elixir Loggerをラップしないでください
Elixirは、強力で便利な伐採施設が
の基本的な使い方
これを実現する一つの方法は、下位レベルのログ記録モジュールをラップすることです.これは完全に自然なことです.プロジェクトが成長するにつれて、コンベンションと抽象的な繰り返しコードを強制するために、より低いレベルの機能をラップします.
それで、あなたはエリクサーのものを包むのが完全に妥当であると思います
ここで問題があります.次のラッパーモジュールを作成することで、このソリューションを実装し始めます.
問題はログAPI関数などです
マクロはどんなファイルを知っていますか
配置することによって
ログマクロを全くラップしないでください.あなたはおそらくいくつかの他の手段によって欲しいものを達成することができます.ドキュメントを見てください
あなたがElixirロガーに呼び出しをラップすることを主張するならば、それをマクロで包みなさい.
マクロとして利用可能な情報の種類のデモンストレーションとして、ここで代替マクロです
Logger
モジュールです.それはエリクサーのプロジェクトで普遍的に使用されます.そして、それはロギング話がはるかにより簡単でない大部分の他の言語でよりはるかにElixirで接近できるようになります.の基本的な使い方
Logger
あなたのために十分かもしれない、ほとんどの時間が、時には、それのいくつかの側面をカスタマイズする必要が発生します.これを実現する一つの方法は、下位レベルのログ記録モジュールをラップすることです.これは完全に自然なことです.プロジェクトが成長するにつれて、コンベンションと抽象的な繰り返しコードを強制するために、より低いレベルの機能をラップします.
それで、あなたはエリクサーのものを包むのが完全に妥当であると思います
Logger
モジュールを参照してください.ここで問題があります.次のラッパーモジュールを作成することで、このソリューションを実装し始めます.
defmodule MyLogger do
require Logger
def info(message, metadata \\ []) do
Logger.info("[myprefix] " <> message, metadata)
end
end
初めはすべてうまくいっているようです.この新しいラッパー関数を別のモジュールから呼び出し、defmodule Example do
def work() do
MyLogger.info("working...")
end
end
iex(2)> Example.work
11:38:16.428 [info] [myprefix] working ...
問題は、通常のログメッセージと一緒にソースの位置情報を含めることを決定するときに発見されます.import Config
config :logger, :console,
metadata: [:file, :function, :module]
iex(1)> Example.work
14:00:03.912 file=lib/my_logger.ex function=info/2 module=MyLogger [info] [myprefix] working ...
ご覧のように、すべてのログ行は、ログイベントのソースを新しいラッピングコードとして報告します.これはあなたが欲しかったものではありません.何が問題ですか。
問題はログAPI関数などです
Logger.info
and Logger.debug
, 関数ではなくマクロであり、この文脈では、あなたがどこで呼ぶのかが問題です.マクロはどんなファイルを知っていますか
__CALLER__
特別な形.実際、それは正確にどのようにLogger
この情報をキャプチャします.配置することによって
Logger.info
つの場所で呼び出し(そして、関数でそれを呼ぶ)、誤ってログ記録システムにすべてのログイベントがその1つの場所から発信することを通知しました.解決策は?
ログマクロを全くラップしないでください.あなたはおそらくいくつかの他の手段によって欲しいものを達成することができます.ドキュメントを見てください
Custom Formatting
ログイベントをログラインにシリアル化する方法をカスタマイズします.エリクシールLoggerがあなたのために十分に柔軟でないならば、より低いレベルを見て検討してくださいErlang Logger オプションです.ログインログを本当にラップしたい
あなたがElixirロガーに呼び出しをラップすることを主張するならば、それをマクロで包みなさい.
defmodule MyLogger do
# I don't recommend doing this
defmacro info(message, metadata \\ []) do
quote do
require Logger
Logger.info("[myprefix] " <> unquote(message), unquote(metadata))
end
end
end
iex(1)> Example.work
13:09:48.324 file=lib/example.ex function=work/0 module=Example [info] [myprefix] working ...
この理由はマクロへの呼び出しであるLogger.info/2
今すぐ呼び出しのコンテキストで展開MyLogger.info/2
, したがって、ソースの位置情報が保存されます.マクロとして利用可能な情報の種類のデモンストレーションとして、ここで代替マクロです
defmodule MyLogger do
defmacro info(message, metadata \\ []) do
env = __CALLER__
quote bind_quoted: [
message: message,
metadata: metadata,
file: env.file,
line: env.line
] do
require Logger
Logger.info("source=#{Path.basename(file)}:#{line} #{message}", metadata)
end
end
end
iex(3)> Example.work
13:20:14.575 [info] source=example.ex:5 working ...
Reference
この問題について(Elixir Loggerをラップしないでください), 我々は、より多くの情報をここで見つけました https://dev.to/aymanosman/dont-wrap-the-elixir-logger-or-be-careful-if-you-do-1ln7テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol