ExUnit.CaptureIO.capture_io not capturing custom logger backend's output to :stdio. Why?

Hi, guys!

I am in need of custom backend for the logger, which I kind of put together from Ink. Basically, the backend writes the messages in my format to :stdio. Now, I am trying to test it and decided to use ExUnit.CaptureIO. For some reason logged messages are not being captured.

Basically, I do the following in the code:

test "metadata overwrite" do
  captures = ExUnit.CaptureIO.capture_io(:stdio, fn ->
    Logger.info "test info no traces"
  end)
  ....
end

what I see on the console:

{"timestamp":"2017-12-16T12:39:31.506Z","module":"Elixir.Logger.JSONBackendTest","message":"test info no traces","line":14,"level":"info","erlang_pid":"#PID<0.137.0>","application":"elixir_common"}

but captures variable is “”

What gives?

Here is my logger config:

config :logger,
  backends: [Logger.Backend.JSON

config :logger, Logger.Backend.JSON,
  level: :info,
  metadata: [:pid, :application, :user_id, :line, :module, :id, :trace, :parent]

Anyone has any clues as to what might be going sideways?
I understand that Logger uses gen_event to push log messages to the backend, so it is all an async process and all but for example doing this did not help:

captures = ExUnit.CaptureIO.capture_io(:stdio, fn ->
   Logger.info "test info no traces"
   Process.sleep(100)
end)

I see that the message now gets printed before the test ends but I still do not have it captured. I also did this:

captures = ExUnit.CaptureIO.capture_io(:stdio, fn ->
   Io.puts "test"
end)

and this worked just fine. Looks like group_leader for the Logger and group leader for the test are not the same. And so ExUnit.CaptureIO is not replacing the desired group leader.

Maybe try ExUnit.CaptureLog.capture_log/1 instead of CaptureIO ?

1 Like

CaptureLog only works with console backend. Obviously, it is not solving anything for me and I did look into it.