defmodule TimeLog.PreLogPlug do
require Logger
alias TimeLog.TimePlug
@moduledoc ~S"""
This plug logs the incoming requests.
It logs the IP address and has the ability to anonymize the IP address if set in config.
"""
@doc false
def init(_opts) do
{}
end
@doc "Call to PreLogPlug that initiates the request logging."
@spec call(Plug.Conn, Map) :: Plug.Conn
def call(conn, _opts) do
if is_list(TimePlug.from_config(:ignore_urls)) and
conn.request_path in TimePlug.from_config(:ignore_urls) do
conn
else
initiate_logging(conn)
end
rescue
e ->
Logger.info("Could not log request due to Exception: #{Exception.format(:error, e, __STACKTRACE__)}")
conn
end
@doc ~S"""
Initiates Response logging and logs the incoming request.
Ensures that responses are only logged if the corresponding request was logged as well.
"""
@spec initiate_logging(Plug.Conn) :: Plug.Conn
def initiate_logging(conn) do
c_id = TimePlug.get_correlation_id(conn)
http_map = %{
method: conn.method,
url: conn.request_path,
query: TimePlug.sanitize_query_string(conn),
ip_address: TimePlug.get_ip(conn),
header: inspect(conn.req_headers),
params: TimePlug.sanitize(conn.params) |> Jason.encode!()
}
http_map =
if TimePlug.from_config(:remove_headers?) do
Map.drop(http_map, [:header])
else
http_map
end
%{
correlation_id: c_id,
type: "Request",
http: http_map
}
|> Jason.encode!()
|> Logger.info(request_log: 1)
Plug.Conn.register_before_send(conn, &TimePlug.log_response(&1))
end
end