Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#34] logger behaviour #36

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/dayron/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,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 Down
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
52 changes: 52 additions & 0 deletions lib/dayron/loggers/basic_logger.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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}) when code < 400 do
Logger.debug fn ->
[inspect_method(request.method), ?\s, request.url, ?\s, "-> #{code}"]
end
log_request_body(:debug, request.body)
end

@doc """
Logs an error message for error response codes, or greater than 400.
"""
def log(request, %Response{status_code: code}) do
Logger.error fn ->
[inspect_method(request.method), ?\s, request.url, ?\s, "-> #{code}"]
end
log_request_body(:error, request.body)
end

@doc """
Logs an error message for response error/exception.
"""
def log(request, %ClientError{reason: reason}) do
Logger.error fn ->
[inspect_method(request.method), ?\s, request.url, ?\s, "-> #{reason}"]
end
log_request_body(:error, request.body)
end

defp inspect_method(method) do
method |> Atom.to_string |> String.upcase
end

defp log_request_body(level, nil), do: :ok
defp log_request_body(level, body) do
if Enum.any?(body) do
Logger.log level, fn ->
["Request body:", ?\s, inspect(body, pretty: true)]
end
end
end

end
23 changes: 11 additions & 12 deletions lib/dayron/repo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ defmodule Dayron.Repo do
{_request, response} =
config
|> Config.init_request_data(:get, model, id: id)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 200, body: body} ->
Expand All @@ -249,7 +249,7 @@ defmodule Dayron.Repo do
{request, response} =
config
|> Config.init_request_data(:get, model, id: id)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 200, body: body} ->
Expand All @@ -264,7 +264,7 @@ defmodule Dayron.Repo do
{_request, response} =
config
|> Config.init_request_data(:get, model)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 200, body: body} ->
Expand All @@ -277,7 +277,7 @@ defmodule Dayron.Repo do
{request, response} =
config
|> Config.init_request_data(:post, model, body: data)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 201, body: body} ->
Expand All @@ -300,7 +300,7 @@ defmodule Dayron.Repo do
{request, response} =
config
|> Config.init_request_data(:patch, model, data)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 200, body: body} ->
Expand Down Expand Up @@ -328,7 +328,7 @@ defmodule Dayron.Repo do
{request, response} =
config
|> Config.init_request_data(:delete, model, id: id)
|> execute!(adapter, opts, config)
|> execute!(adapter, opts, Config.get_logger(config))

case response do
%Dayron.Response{status_code: 200, body: body} ->
Expand All @@ -352,11 +352,11 @@ defmodule Dayron.Repo do
end
end

defp execute!(%Request{} = request, adapter, opts, config) do
defp execute!(%Request{} = request, adapter, opts, logger) do
request
|> Request.send(adapter, opts)
|> log_request(logger)
|> handle_errors(opts)
|> log_response(config)
end

defp handle_errors({request, response}, _opts) do
Expand All @@ -371,10 +371,9 @@ defmodule Dayron.Repo do
end
end

defp log_response({request, response}, config) do
if Config.log_responses?(config) do
Logger.log(request.method, request.url, response)
end
defp log_request(data, nil), do: data
defp log_request({request, response}, logger) do
:ok = logger.log(request, response)
{request, response}
end
end
14 changes: 12 additions & 2 deletions test/lib/dayron/config_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,19 @@ defmodule Dayron.ConfigTest do
assert adapter == Dayron.HTTPoisonAdapter
end

test "returns default value for log_responses?" do
test "returns default value for get_logger?" do
{_, _, config} = Config.parse(Dayron.Repo, otp_app: :dayron_test)
assert Config.log_responses?(config)
assert Config.get_logger(config) == Dayron.BasicLogger
end

defmodule MyLogger do

end

test "returns application logger config" do
Application.put_env(:dayron_test, Dayron.Repo, [url: "http://api.example.com", logger: MyLogger])
{_, _, config} = Config.parse(Dayron.Repo, otp_app: :dayron_test)
assert Config.get_logger(config) == MyLogger
end

defmodule MyModel do
Expand Down
2 changes: 1 addition & 1 deletion test/support/test_repo.exs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ defmodule Dayron.TestAdapter do
end
end

Application.put_env(:dayron, Dayron.TestRepo, [url: "http://localhost", enable_log: false])
Application.put_env(:dayron, Dayron.TestRepo, [url: "http://localhost", logger: nil])

defmodule Dayron.TestRepo do
use Dayron.Repo, otp_app: :dayron, adapter: Dayron.TestAdapter
Expand Down