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