rwdaigle / metrix

Elixir library to log custom application metrics, in a well-structured, human and machine readable format, for use by downstream log processing systems (Librato, Reimann, etc...)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Logger.info instead of IO.puts

sergiobuj opened this issue · comments

Hi,

I noted the Logger/log level integration in the todo list. I am currently getting my metrics when running tests and is adding unnecessary noise.

This diff works great for me but wanted to know your original idea for the level integration.

diff --git a/lib/metrix.ex b/lib/metrix.ex
index 8be6632..ed8179f 100644
--- a/lib/metrix.ex
+++ b/lib/metrix.ex
@@ -70,5 +70,5 @@ defmodule Metrix do

   defp add(dict, key, value), do: dict |> Dict.put(key, value)

-  defp write(output), do: output |> IO.puts
+  defp write(output), do: output |> Logger.info
 end

Hi @sergiobuj, thanks for this!

So my initial thought is that I'd like the output target to be configurable. In production I actually do want it to go to STDOUT, but in test I might want it silenced or to go to a file.

What are your thoughts on how that would be handled?

@sergiobuj @rwdaigle I think an alternative is using Logger.log and then the user can take care of the logging level and backend (file, console, etc) using logger configuration.

In default config.exs we can have something like:

config :metrix,
  log_level: :info

And of course this can be changed per-env in test.exs, dev.exs and prod.exs files.

Then in the code we can have something like this:

defp write(output) do
  level = Application.get_env(:metrix, :log_level, :info) # or maybe we should fallback to `:debug` by default?
  Logger.log(level, output)
end

What do you think?

@guilleiguaran this might not be idiomatic Elixir, but what about a solution that lets the user pass in a function that does the writing?

config :metrix,
  write: fn output -> Logger.log(:info, output) end

Then in Metrix:

defp write(output) do
  print = Application.get_env(:metrix, :write) || fn output -> IO.puts output end
  print(output)
end

Seems like this approach provides a lot of flexibility. Are there any downsides?

@rwdaigle I'm not sure if it's idiomatic Elixir neither but one problem I see with that approach is that Erlang Releases tools for Elixir (relex, exrm, ...) will fail trying to generate a standard Erlang sys.config from the config.exs because the anonymous function can't be directly translated to an Erlang term.

one problem I see with that approach is that Erlang Releases tools for Elixir (relex, exrm, ...) will fail trying to generate a standard Erlang sys.config from the config.exs because the anonymous function can't be directly translated to an Erlang term

I would have never thought of that, thanks @guilleiguaran!

So it definitely feels like using the Logger is the right approach here. There are just too many benefits like buffering, back-pressure, configuration etc.., to not use it. Also, the Logger defaults to using :console (STDOUT).

@sergiobuj if you want to put a PR together using Logger and @guilleiguaran's log-level config idea I'd be happy to pull it in? Let me know if that's something you want to do!