Skip to content

Commit

Permalink
Merge pull request #37 from inaka/flavio.33.inspect-request-response
Browse files Browse the repository at this point in the history
[#33] inspect request response, better logging
  • Loading branch information
alemata committed May 16, 2016
2 parents 87b7451 + 21be1c0 commit 38f24ee
Show file tree
Hide file tree
Showing 14 changed files with 414 additions and 162 deletions.
8 changes: 4 additions & 4 deletions lib/dayron/adapters/httpoison_adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,31 @@ defmodule Dayron.HTTPoisonAdapter do
"""
def get(url, headers \\ [], opts \\ []) do
Client.start
Client.get(url, headers, opts) |> translate_response
url |> Client.get(headers, opts) |> translate_response
end

@doc """
Implementation for `Dayron.Adapter.post/4`.
"""
def post(url, body, headers \\ [], opts \\ []) do
Client.start
Client.post(url, body, headers, opts) |> translate_response
url |> Client.post(body, headers, opts) |> translate_response
end

@doc """
Implementation for `Dayron.Adapter.patch/4`.
"""
def patch(url, body, headers \\ [], opts \\ []) do
Client.start
Client.patch(url, body, headers, opts) |> translate_response
url |> Client.patch(body, headers, opts) |> translate_response
end

@doc """
Implementation for `Dayron.Adapter.delete/3`.
"""
def delete(url, headers \\ [], opts \\ []) do
Client.start
Client.delete(url, headers, opts) |> translate_response
url |> Client.delete(headers, opts) |> translate_response
end

defp translate_response({:ok, response}) do
Expand Down
10 changes: 6 additions & 4 deletions lib/dayron/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Dayron.Config do
otp_app = Keyword.fetch!(opts, :otp_app)
config = Application.get_env(otp_app, repo, [])
adapter = opts[:adapter] || config[:adapter] || Dayron.HTTPoisonAdapter
logger = get_logger(config)

case parse_url(opts[:url] || config[:url]) do
{:ok, url} -> config = Keyword.put(config, :url, url)
Expand All @@ -22,7 +23,7 @@ defmodule Dayron.Config do
"config #{inspect otp_app}, #{inspect repo}"
end

{otp_app, adapter, config}
{otp_app, adapter, logger, config}
end

@doc """
Expand All @@ -49,8 +50,8 @@ defmodule Dayron.Config do
Based on application configuration, returns a boolean indicating if reponses
log is enabled
"""
def log_responses?(config) do
Keyword.get(config, :enable_log, true)
def get_logger(config) do
Keyword.get(config, :logger, Dayron.BasicLogger)
end

@doc """
Expand All @@ -61,7 +62,8 @@ defmodule Dayron.Config do
method: method,
url: get_request_url(config, model, opts),
body: opts[:body],
headers: get_headers(config)
headers: get_headers(config),
options: opts[:options]
}
end

Expand Down
37 changes: 18 additions & 19 deletions lib/dayron/exceptions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ defmodule Dayron.NoResultsError do
@moduledoc """
Raised at runtime when the request does not return any result.
"""
defexception [:url, :method]
defexception [:request]

def message(%{url: url, method: method}) do
def message(%{request: request}) do
"""
expected at least one result but got none in request:
#{method} #{url}
#{inspect request, pretty: true}
"""
end
end
Expand All @@ -18,17 +18,18 @@ defmodule Dayron.ServerError do
@moduledoc """
Raised at runtime when the request returns an error.
"""
defexception [:url, :method, :body]
defexception [:request, :response]

def message(%{url: url, method: method, body: body}) do
def message(%{request: request, response: response}) do
"""
unexpected response error in request:
#{method} #{url}
#{inspect request, pretty: true}
* Server Error
#{inspect response, pretty: true}
#{inspect body}
Response Body:
#{inspect response.body, pretty: true}
"""
end
end
Expand All @@ -37,17 +38,15 @@ defmodule Dayron.ClientError do
@moduledoc """
Raised at runtime when the request connection fails.
"""
defexception [:id, :url, :method, :reason]
defexception [:id, :reason, :request]

def message(%{url: url, method: method, reason: reason}) do
def message(%{request: request, reason: reason}) do
"""
unexpected client error in request:
#{method} #{url}
#{inspect request, pretty: true}
* Reason:
#{inspect reason}
* Reason: #{inspect reason}
"""
end
end
Expand All @@ -57,17 +56,17 @@ defmodule Dayron.ValidationError do
@moduledoc """
Raised at runtime when the response is a 422 unprocessable entity.
"""
defexception [:url, :method, :response]
defexception [:request, :response]

def message(%{url: url, method: method, response: response}) do
def message(%{request: request, response: response}) do
"""
validation error in request:
#{method} #{url}
#{inspect request, pretty: true}
* Response (422):
* Response:
#{inspect response}
#{inspect response, pretty: true}
"""
end
end
57 changes: 19 additions & 38 deletions lib/dayron/logger.ex
Original file line number Diff line number Diff line change
@@ -1,47 +1,28 @@
defmodule Dayron.Logger do
@moduledoc """
Helper module wrapping Logger calls to register request/response events
"""
require Logger
alias Dayron.Response
alias Dayron.ClientError
@moduledoc ~S"""
Behaviour for creating Dayron Loggers
@doc """
Logs a debug or error message based on response code.
"""
def log(method, url, response, req_details \\ []) do
do_log(method, url, response, req_details)
response
end
Loggers are responsible to print request and response data to an output.
@doc """
Logs a debug message for response codes between 200-399.
"""
def do_log(method, url, %Response{status_code: code}, req_details) when code < 400 do
Logger.debug [method, ?\s, url, ?\s, "-> #{code}"]
log_request_details :debug, req_details
end
## Example
@doc """
Logs an error message for error response codes, or greater than 400.
defmodule Dayron.CustomLogger do
@behaviour Dayron.Logger
require Logger
def log(request, response) do
Logger.debug(inspect(request))
Logger.debug(inspect(response))
end
end
"""
def do_log(method, url, %Response{status_code: code}, req_details) do
Logger.error [method, ?\s, url, ?\s, "-> #{code}"]
log_request_details :debug, req_details
end
alias Dayron.Request
alias Dayron.Response
alias Dayron.ClientError

@doc """
Logs an error message for response error/exception.
Logs an message based on request and response data.
"""
def do_log(method, url, %ClientError{reason: reason}, req_details) do
Logger.error [method, ?\s, url, ?\s, "-> #{reason}"]
log_request_details :error, req_details
end

defp log_request_details(level, req_details) do
if Enum.any?(req_details) do
Logger.log(level, "Request: \n #{inspect req_details, pretty: true}")
end
end

@callback log(Request.t, Response.t | ClientError.t) :: atom
end
34 changes: 34 additions & 0 deletions lib/dayron/loggers/basic_logger.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule Dayron.BasicLogger do
@moduledoc """
Helper module wrapping Logger calls to register request/response events
"""
require Logger
alias Dayron.Response
alias Dayron.ClientError

@doc """
Logs a debug message for response codes between 200-399.
"""
def log(request, %Response{status_code: code} = response) when code < 400 do
do_log(:debug, request, response)
end

@doc """
Logs an error message for error response codes, or greater than 400.
"""
def log(request, %Response{} = response), do:
do_log(:error, request, response)

@doc """
Logs an error message for response error/exception.
"""
def log(request, %ClientError{} = response) do
response = %{response | request: request}
Logger.error ClientError.message(response)
end

defp do_log(level, request, response) do
Logger.log level, inspect(request, pretty: true)
Logger.log level, inspect(response, pretty: true)
end
end
Loading

0 comments on commit 38f24ee

Please sign in to comment.