Skip to content

Commit ba86beb

Browse files
authored
Fix "always evaluate" for Logger anonymous function tuples (#15081)
Previously, when the configuration directive `always_evaluate_messages` was set to true an exception was raised when a function that returns a tuple was given to Logger: ``` Logger.info(fn -> {"", []} end) ``` Would result in: ``` ** (Protocol.UndefinedError) protocol String.Chars not implemented for Tuple Got value: {"", []} ```
1 parent 5093bab commit ba86beb

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

lib/logger/lib/logger.ex

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,12 +1016,15 @@ defmodule Logger do
10161016
end
10171017

10181018
@doc false
1019-
def __evaluate_log__(data) when is_function(data, 0) do
1020-
data.()
1019+
def __evaluate_log__(data, metadata) when is_function(data, 0) do
1020+
case data.() do
1021+
{msg, new_metadata} -> {msg, Enum.into(new_metadata, metadata)}
1022+
data -> {data, metadata}
1023+
end
10211024
end
10221025

1023-
def __evaluate_log__(data) do
1024-
data
1026+
def __evaluate_log__(data, metadata) do
1027+
{data, metadata}
10251028
end
10261029

10271030
@doc false
@@ -1151,8 +1154,7 @@ defmodule Logger do
11511154

11521155
Application.get_env(:logger, :always_evaluate_messages, false) ->
11531156
quote do
1154-
data = Logger.__evaluate_log__(unquote(data))
1155-
metadata = unquote(quoted_metadata)
1157+
{data, metadata} = Logger.__evaluate_log__(unquote(data), unquote(quoted_metadata))
11561158

11571159
case Logger.__should_log__(unquote(level), __MODULE__) do
11581160
nil -> :ok
@@ -1259,8 +1261,7 @@ defmodule Logger do
12591261
defp no_log(data, metadata) do
12601262
if Application.get_env(:logger, :always_evaluate_messages, false) do
12611263
quote do
1262-
Logger.__evaluate_log__(unquote(data))
1263-
unquote(metadata)
1264+
Logger.__evaluate_log__(unquote(data), unquote(metadata))
12641265
:ok
12651266
end
12661267
else

lib/logger/test/logger_test.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ defmodule LoggerTest do
650650
Logger.configure(translator_inspect_opts: [])
651651
end
652652

653+
@tag formatter: [metadata: [:module, :meta]]
653654
test "always evaluate messages" do
654655
Logger.configure(
655656
always_evaluate_messages: true,
@@ -666,6 +667,16 @@ defmodule LoggerTest do
666667
Logger.info(send(self(), "runtime purged"))
667668
end
668669

670+
def runtime_purged_anonymous_function do
671+
Logger.info(fn -> send(self(), "runtime purged anonymous function") end)
672+
end
673+
674+
def runtime_purged_anonymous_tuple_function do
675+
Logger.info(fn ->
676+
{send(self(), "runtime purged anonymous tuple function"), meta: true}
677+
end)
678+
end
679+
669680
def not_purged do
670681
Logger.error(send(self(), "not purged"))
671682
end
@@ -688,6 +699,24 @@ defmodule LoggerTest do
688699

689700
assert_received "runtime purged"
690701

702+
assert capture_log(fn ->
703+
Logger.configure(level: :debug)
704+
AlwaysEvaluate.runtime_purged_anonymous_function()
705+
end) =~ "runtime purged anonymous function"
706+
707+
assert_received "runtime purged anonymous function"
708+
709+
log =
710+
capture_log(fn ->
711+
Logger.configure(level: :debug)
712+
AlwaysEvaluate.runtime_purged_anonymous_tuple_function()
713+
end)
714+
715+
assert log =~ "module=LoggerTest.AlwaysEvaluate meta=true"
716+
assert log =~ "runtime purged anonymous tuple function"
717+
718+
assert_received "runtime purged anonymous tuple function"
719+
691720
assert capture_log(fn ->
692721
Logger.configure(level: :error)
693722
AlwaysEvaluate.compile_purged()

0 commit comments

Comments
 (0)