diff --git a/lib/logger_proxy.ex b/lib/logger_proxy.ex index 907b9b02..58110f7c 100644 --- a/lib/logger_proxy.ex +++ b/lib/logger_proxy.ex @@ -46,16 +46,17 @@ defmodule Mediasoup.LoggerProxy do } end + @type filter_fun :: (Record.t() -> :log | {:log, Record.t()} | :stop | :ignore) @type config :: {:max_level, :off | :error | :warn | :info | :debug} - | {:filter, (Record.t() -> boolean()) | nil} + | {:filters, [filter_fun()]} @spec start_link([config]) :: :ignore | {:error, any} | {:ok, pid} def start_link(config \\ []) do max_level = Keyword.get(config, :max_level, :error) - filter = Keyword.get(config, :filter, nil) + filters = Keyword.get(config, :filters, []) - GenServer.start_link(Mediasoup.LoggerProxy, %{max_level: max_level, filter: filter}, + GenServer.start_link(Mediasoup.LoggerProxy, %{max_level: max_level, filters: filters}, name: __MODULE__ ) end @@ -65,8 +66,16 @@ defmodule Mediasoup.LoggerProxy do {:ok, init_arg} end - def handle_info(%Mediasoup.LoggerProxy.Record{} = msg, %{filter: filter} = state) do - if filter == nil || filter.(msg) do + def handle_info(%Mediasoup.LoggerProxy.Record{} = msg, %{filters: filters} = state) do + with {:log, msg} <- + Enum.reduce_while(filters, {:log, msg}, fn filter, acc -> + case filter.(msg) do + :log -> {:halt, acc} + {:log, changed} -> {:halt, {:log, changed}} + :stop -> {:halt, :stop} + _ -> {:cont, acc} + end + end) do Logger.log(msg.level, msg.body, %{ line: msg.line, file: msg.file, diff --git a/test/logger_proxy_test.exs b/test/logger_proxy_test.exs index a06ec0fd..ad995ad3 100644 --- a/test/logger_proxy_test.exs +++ b/test/logger_proxy_test.exs @@ -85,8 +85,18 @@ defmodule Mediasoup.LoggerProxyTest do end describe "log filter" do - test "filter info only" do - LoggerProxy.start_link(max_level: :debug, filter: fn msg -> msg.level == :info end) + test "filter debug message" do + LoggerProxy.start_link( + max_level: :debug, + filters: [ + fn msg -> + case msg.level do + :debug -> :stop + _ -> :ignore + end + end + ] + ) assert capture_log(fn -> Mediasoup.Nif.debug_logger(:info, "test") @@ -99,17 +109,21 @@ defmodule Mediasoup.LoggerProxyTest do end) =~ "test" end - test "filter can_consume error" do + test "can_consume error should be warn" do pattern = ~r/can_consume\(\) \| Producer with id "(?[^"]+)" not found/ filter_can_consume_error = fn msg -> - msg.level === :error && msg.target === "mediasoup::router" && - Regex.match?(pattern, msg.body) + if msg.level === :error && msg.target === "mediasoup::router" && + Regex.match?(pattern, msg.body) do + {:log, Map.put(msg, :level, :warn)} + else + :ignore + end end LoggerProxy.start_link( max_level: :warn, - filter: filter_can_consume_error + filters: [filter_can_consume_error] ) alias Mediasoup.{Worker, Router} @@ -120,7 +134,17 @@ defmodule Mediasoup.LoggerProxyTest do mediaCodecs: [] }) - assert capture_log(fn -> + assert capture_log([level: :warn], fn -> + Router.can_consume?(router, "d117b485-7490-4146-812f-d3f744f0a8c7", %{ + codecs: [], + headerExtensions: [], + fecMechanisms: [] + }) + + Process.sleep(10) + end) =~ "can_consume() | Producer with id " + + refute capture_log([level: :error], fn -> Router.can_consume?(router, "d117b485-7490-4146-812f-d3f744f0a8c7", %{ codecs: [], headerExtensions: [], @@ -130,5 +154,52 @@ defmodule Mediasoup.LoggerProxyTest do Process.sleep(10) end) =~ "can_consume() | Producer with id " end + + test "multiple filters" do + LoggerProxy.start_link( + max_level: :debug, + filters: [ + fn msg -> + if Regex.match?(~r/should be logged/, msg.body) do + :log + else + :ignore + end + end, + fn msg -> + if msg.level === :debug && Regex.match?(~r/test/, msg.body) do + {:log, Map.put(msg, :level, :info)} + else + :ignore + end + end, + fn msg -> + if msg.level === :warn && Regex.match?(~r/test/, msg.body) do + :stop + else + :ignore + end + end + ] + ) + + assert capture_log([level: :info], fn -> + Mediasoup.Nif.debug_logger(:debug, "debug test") + Mediasoup.Nif.debug_logger(:warn, "warn test") + Process.sleep(10) + end) =~ "debug test" + + refute capture_log(fn -> + Mediasoup.Nif.debug_logger(:info, "info test") + Mediasoup.Nif.debug_logger(:warn, "warn test") + Process.sleep(10) + end) =~ "warn test" + + assert capture_log(fn -> + Mediasoup.Nif.debug_logger(:warn, "warn test") + Mediasoup.Nif.debug_logger(:info, "should be logged") + Process.sleep(10) + end) =~ "should be logged" + end end end