From 64d4dff68718841ee15da8cd9a55f9afa7f84689 Mon Sep 17 00:00:00 2001 From: Flavio Granero Date: Thu, 12 May 2016 17:52:55 -0300 Subject: [PATCH] [#34] adding logger behavior, implementing basic logger, loading logger from application config --- lib/dayron/config.ex | 4 +-- lib/dayron/logger.ex | 57 ++++++++++-------------------- lib/dayron/loggers/basic_logger.ex | 52 +++++++++++++++++++++++++++ lib/dayron/repo.ex | 23 ++++++------ test/lib/dayron/config_test.exs | 14 ++++++-- test/support/test_repo.exs | 2 +- 6 files changed, 97 insertions(+), 55 deletions(-) create mode 100644 lib/dayron/loggers/basic_logger.ex diff --git a/lib/dayron/config.ex b/lib/dayron/config.ex index 42d83f2..17b29a8 100644 --- a/lib/dayron/config.ex +++ b/lib/dayron/config.ex @@ -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 """ diff --git a/lib/dayron/logger.ex b/lib/dayron/logger.ex index 0402fc9..247c020 100644 --- a/lib/dayron/logger.ex +++ b/lib/dayron/logger.ex @@ -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 diff --git a/lib/dayron/loggers/basic_logger.ex b/lib/dayron/loggers/basic_logger.ex new file mode 100644 index 0000000..cb185ce --- /dev/null +++ b/lib/dayron/loggers/basic_logger.ex @@ -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 diff --git a/lib/dayron/repo.ex b/lib/dayron/repo.ex index c8b244c..9c3a0a8 100644 --- a/lib/dayron/repo.ex +++ b/lib/dayron/repo.ex @@ -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} -> @@ -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} -> @@ -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} -> @@ -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} -> @@ -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} -> @@ -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} -> @@ -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 @@ -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 diff --git a/test/lib/dayron/config_test.exs b/test/lib/dayron/config_test.exs index 811544d..a744e2b 100644 --- a/test/lib/dayron/config_test.exs +++ b/test/lib/dayron/config_test.exs @@ -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 diff --git a/test/support/test_repo.exs b/test/support/test_repo.exs index 7700046..cdffb9d 100644 --- a/test/support/test_repo.exs +++ b/test/support/test_repo.exs @@ -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