defmodule Membrane.Log.Router do @moduledoc deprecated: "Use Elixir `Logger` instead" @moduledoc """ Defines a router that dispatches logs to instances of `Membrane.Log.Logger.Base` """ use GenServer alias Membrane.Log.Supervisor @doc """ Starts router as a separate process. Options are passed to `Supervisor.start_link/3`. """ @spec start_link({any, GenServer.options()}) :: GenServer.on_start() def start_link({config, process_options}) do loggers = config |> Keyword.get(:loggers, []) GenServer.start_link(__MODULE__, loggers, process_options) end @doc """ Sends asynchronous call to the router, requesting it to forward log message to appropriate loggers. This functions assumes that passed log has level equal or greater than global level. """ @spec send_log(atom, any, String.t(), [atom]) :: :ok def send_log(level, message, time, tags \\ []) do Membrane.Log.Router |> send({:membrane_log, level, message, time, tags}) :ok end @doc """ Converts atom with level to its number representation Valid atoms are: - :debug - :info - :warn """ @spec level_to_val(Membrane.Log.level_t()) :: 0 | 1 | 2 def level_to_val(:debug), do: 0 def level_to_val(:info), do: 1 def level_to_val(:warn), do: 2 # PRIVATE API @impl true def init(loggers) do loggers = loggers |> Enum.into(%{}, fn %{id: id} = logger_map -> level = logger_map |> Map.get(:level, :debug) tags = logger_map |> Map.get(:tags, [:all]) |> MapSet.new() {id, %{level: level, tags: tags}} end) {:ok, %{loggers: loggers}} end # Forwards log to every logger that has low enough level and has at least one # common tag with the message @impl true def handle_info( {:membrane_log, log_level, _message, _time, tags} = log, %{loggers: loggers} = state ) do Supervisor.each_logger(fn {id, pid, _type, _module} -> logger = loggers |> Map.get(id) if logger |> accepts_level?(log_level) and logger |> accepts_any_tag?(tags) do send(pid, log) end end) {:noreply, state} end defp accepts_level?(%{level: logger_lvl}, lvl) do level_to_val(logger_lvl) <= level_to_val(lvl) end defp accepts_any_tag?(%{tags: logger_tags}, tags) do tags = MapSet.new([:all | tags]) not MapSet.disjoint?(logger_tags, tags) end end