defmodule Log.Reset.LogPaths do @moduledoc """ A map of configured log paths and functions. """ use PersistConfig # Must be in that order given the common 'Log' part... alias Log.Reset alias Log.Reset.Log @typedoc "A map assigning configured log paths to their log levels" @type t :: %{Logger.level() => Path.t()} @doc """ Resets the configured log files of the given `levels`. ## Examples iex> alias Log.Reset.LogPaths # The parent app may not configure any file handlers... iex> LogPaths.reset_logs([], :all) :ok iex> alias Log.Reset.LogPaths iex> LogPaths.reset_logs([], [:info, :error]) :ok """ @spec reset_logs(t, Reset.levels()) :: :ok def reset_logs(log_paths, :all) when is_map(log_paths) do log_paths |> Map.values() |> reset_logs() end def reset_logs(_log_paths, :none), do: :ok def reset_logs(log_paths, levels) when is_map(log_paths) and is_list(levels) do for {level, log_path} <- log_paths, level in levels do log_path end |> reset_logs() end def reset_logs(_log_paths, _), do: :ok @doc """ Creates a map assigning each configured log path to its log level. """ @spec new :: t def new do for {:handler, _handler_id, :logger_std_h, %{level: level, config: %{file: path}}} <- get_app_env(:file_only_logger, :logger, []), into: %{}, do: {level, path} end ## Private functions @spec reset_logs([Path.t()]) :: :ok defp reset_logs(log_paths) do log_paths # Truncate log files first... |> Enum.map(&Task.async(fn -> reset_log(&1) end)) |> Enum.map(&Task.await/1) # Log reset results second... |> log_results() end @spec log_results([tuple]) :: :ok defp log_results(results) do Enum.reduce(results, :ok, fn {:ok, log_path}, _acc -> :ok = Log.info(:log_reset, {log_path, __ENV__}) {:error, reason, log_path}, _acc -> :ok = Log.error(:log_not_reset, {log_path, reason, __ENV__}) end) end @spec reset_log(Path.t()) :: tuple defp reset_log(log_path) do log_path = Path.expand(log_path) # `File.rm/1` would prevent logging results when file_check > 0. case File.open(log_path, [:write]) do {:ok, _pid} -> {:ok, log_path} {:error, :enoent} -> {:ok, log_path} {:error, reason} -> {:error, reason, log_path} end end end