defmodule DaProductApp.LogFormatter do def format(level, message, timestamp, metadata) do {{y, mo, d}, {h, mi, s, ms}} = timestamp weekday = day_of_week_abbr(Date.day_of_week(Date.new!(y, mo, d))) month = month_abbr(mo) day = String.pad_leading(Integer.to_string(d), 2) ts = "[#{weekday} #{month} #{day} #{pad(h, 2)}:#{pad(mi, 2)}:#{pad(s, 2)}.#{pad(ms * 1000, 6)} #{y}]" mod_name = case Keyword.get(metadata, :module) do nil -> "da_product_app" mod -> mod |> Atom.to_string() |> String.replace_prefix("Elixir.", "") end lvl = level |> Atom.to_string() |> String.downcase() pid = :os.getpid() |> List.to_string() client = case Keyword.get(metadata, :peer) do {ip, port} -> "#{format_ip(ip)}:#{port}" nil -> case Keyword.get(metadata, :remote_ip) do nil -> "-" ip -> format_ip(ip) end end "#{ts} [#{mod_name}:#{lvl}] [pid #{pid}] [client #{client}] #{format_msg(message)}\n" rescue _ -> "[#{level}] #{inspect(message)}\n" end defp day_of_week_abbr(1), do: "Mon" defp day_of_week_abbr(2), do: "Tue" defp day_of_week_abbr(3), do: "Wed" defp day_of_week_abbr(4), do: "Thu" defp day_of_week_abbr(5), do: "Fri" defp day_of_week_abbr(6), do: "Sat" defp day_of_week_abbr(7), do: "Sun" defp month_abbr(1), do: "Jan" defp month_abbr(2), do: "Feb" defp month_abbr(3), do: "Mar" defp month_abbr(4), do: "Apr" defp month_abbr(5), do: "May" defp month_abbr(6), do: "Jun" defp month_abbr(7), do: "Jul" defp month_abbr(8), do: "Aug" defp month_abbr(9), do: "Sep" defp month_abbr(10), do: "Oct" defp month_abbr(11), do: "Nov" defp month_abbr(12), do: "Dec" defp format_ip({a, b, c, d}), do: "#{a}.#{b}.#{c}.#{d}" defp format_ip(ip), do: inspect(ip) defp format_msg({:report, report}), do: inspect(report) defp format_msg(msg), do: IO.chardata_to_string(msg) defp pad(n, size), do: n |> Integer.to_string() |> String.pad_leading(size, "0") end