Skip to content
Permalink
Browse files
Code for step 3
  • Loading branch information
akoutmos committed Mar 10, 2020
1 parent 14b439b commit 714ab4b3674eecd35b792687c4a3d4b774cfe47b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 4 deletions.
@@ -19,12 +19,16 @@ config :auto_finder, AutoFinderWeb.Endpoint,
live_view: [signing_salt: "60QXfDxg"]

# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
config :logger, backends: [LoggerJSON]
config :auto_finder, AutoFinder.Repo, loggers: [{LoggerJSON.Ecto, :log, [:info]}]

config :logger_json, :backend,
metadata: [:file, :line, :function, :module, :application, :httpRequest, :query],
formatter: AutoFinder.LoggerFormatter

# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
config :phoenix, :logger, false

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
@@ -5,7 +5,7 @@ config :auto_finder, AutoFinder.Repo,
username: "postgres",
password: "postgres",
database: "auto_finder_dev",
hostname: "localhost",
hostname: "postgres",
show_sensitive_data_on_connection_error: true,
pool_size: 10

@@ -16,6 +16,15 @@ defmodule AutoFinder.Application do
# {AutoFinder.Worker, arg},
]

# Attach Telemetry handler for Ecto events
:ok =
:telemetry.attach(
"logger-json-ecto",
[:auto_finder, :repo, :query],
&LoggerJSON.Ecto.telemetry_logging_handler/4,
:info
)

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: AutoFinder.Supervisor]
@@ -14,6 +14,8 @@ defmodule AutoFinderWeb.Endpoint do
websocket: true,
longpoll: false

plug LoggerJSON.Plug

# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phx.digest
@@ -0,0 +1,103 @@
defmodule AutoFinder.LoggerFormatter do
@moduledoc """
Custom Formatter
"""
import Jason.Helpers, only: [json_map: 1]

@behaviour LoggerJSON.Formatter

@processed_metadata_keys ~w[pid file line function module application]a

@severity_levels [
debug: "DEBUG",
info: "INFO",
warning: "WARNING",
warn: "WARNING",
error: "ERROR"
]

for {level, gcp_level} <- @severity_levels do
def format_event(unquote(level), msg, ts, md, md_keys) do
Map.merge(
%{
time: format_timestamp(ts),
severity: unquote(gcp_level),
message: IO.iodata_to_binary(msg)
},
format_metadata(md, md_keys)
)
end
end

def format_event(_level, msg, ts, md, md_keys) do
Map.merge(
%{
time: format_timestamp(ts),
severity: "DEFAULT",
message: IO.iodata_to_binary(msg)
},
format_metadata(md, md_keys)
)
end

defp format_metadata(md, md_keys) do
LoggerJSON.take_metadata(md, md_keys, @processed_metadata_keys)
|> maybe_put(:error, format_process_crash(md))
end

defp maybe_put(map, _key, nil), do: map
defp maybe_put(map, key, value), do: Map.put(map, key, value)

defp format_process_crash(md) do
if crash_reason = Keyword.get(md, :crash_reason) do
initial_call = Keyword.get(md, :initial_call)

json_map(
initial_call: format_initial_call(initial_call),
reason: format_crash_reason(crash_reason)
)
end
end

defp format_initial_call(nil), do: nil

defp format_initial_call({module, function, arity}),
do: "#{module}.#{function}/#{arity}"

defp format_crash_reason({:throw, reason}) do
Exception.format(:throw, reason)
end

defp format_crash_reason({:exit, reason}) do
Exception.format(:exit, reason)
end

defp format_crash_reason({%{} = exception, stacktrace}) do
Exception.format(:error, exception, stacktrace)
end

defp format_crash_reason(other) do
inspect(other)
end

# RFC3339 UTC "Zulu" format
defp format_timestamp({date, time}) do
[format_date(date), ?T, format_time(time), ?Z]
|> IO.iodata_to_binary()
end

defp format_time({hh, mi, ss, ms}) do
[pad2(hh), ?:, pad2(mi), ?:, pad2(ss), ?., pad3(ms)]
end

defp format_date({yy, mm, dd}) do
[Integer.to_string(yy), ?-, pad2(mm), ?-, pad2(dd)]
end

defp pad3(int) when int < 10, do: [?0, ?0, Integer.to_string(int)]
defp pad3(int) when int < 100, do: [?0, Integer.to_string(int)]
defp pad3(int), do: Integer.to_string(int)

defp pad2(int) when int < 10, do: [?0, Integer.to_string(int)]
defp pad2(int), do: Integer.to_string(int)
end

0 comments on commit 714ab4b

Please sign in to comment.