@@ -231,18 +231,29 @@ defmodule ExUnit.CaptureServer do
231231 ## :logger handler callback.
232232
233233 def log ( event , _config ) do
234- for { _ref , string_io , level , formatter_mod , formatter_config } <- :ets . tab2list ( @ ets ) ,
235- :logger . compare_levels ( event . level , level ) in [ :gt , :eq ] do
236- chardata = formatter_mod . format ( event , formatter_config )
237- # There is a race condition where the capture_log is removed
238- # but another process is attempting to log to string io device
239- # that no longer exists, so we wrap it in try/catch.
240- try do
241- IO . write ( string_io , chardata )
242- rescue
243- _ -> :ok
234+ :ets . tab2list ( @ ets )
235+ |> Enum . filter ( fn { _ref , _string_io , level , _formatter_mod , _formatter_config } ->
236+ :logger . compare_levels ( event . level , level ) in [ :gt , :eq ]
237+ end )
238+ |> Enum . group_by (
239+ fn { _ref , _string_io , _level , formatter_mod , formatter_config } ->
240+ { formatter_mod , formatter_config }
241+ end ,
242+ fn { _ref , string_io , _level , _formatter_mod , _formatter_config } ->
243+ string_io
244244 end
245- end
245+ )
246+ |> Enum . map ( fn { { formatter_mod , formatter_config } , string_ios } ->
247+ Task . async ( fn ->
248+ chardata = formatter_mod . format ( event , formatter_config )
249+
250+ # Simply send, do not wait for reply
251+ for string_io <- string_ios do
252+ send ( string_io , { :io_request , self ( ) , make_ref ( ) , { :put_chars , :unicode , chardata } } )
253+ end
254+ end )
255+ end )
256+ |> Task . await_many ( :infinity )
246257
247258 :ok
248259 end
0 commit comments