Passes `capture_log: true` to ExUnit.start/1 so log output emitted
during a passing test stays in the per-test capture buffer instead of
stdout. Drops ~360 lines of noise from the suite: Postgrex teardown
disconnects, expected worker failures, NexradClient 404 stubs,
NotifyListener warm-skip messages, SNMP poll failures, PromEx tag-
drop warnings, and OTel-handler boot errors. Failing tests still
surface their full logs on report, so debugging is unchanged.
Side-effect fixes:
- LoggerFormatTest opts out via @moduletag capture_log: false — it
patches the :default :logger handler and capture_log hot-swaps the
same handler, so the setup lookup would 404.
- TelemetryTest.start_link/1 unlinks the supervisor before the brutal
kill so the exit signal doesn't propagate to the test process.
- Drop unused `import Ecto.Query` in a top_hours mix-task test.
- Drop unused default-arg `attrs \\ %{}` on create_contact/1 in
contact_map_live_test (every caller passes attrs explicitly).
Remaining noise is ~3 lines from oban_pro vendored-dep @impl warnings
(require an upstream patch) plus rare intermittent async teardowns.
65 lines
2.3 KiB
Elixir
65 lines
2.3 KiB
Elixir
defmodule Microwaveprop.LoggerFormatTest do
|
|
# async: false — we briefly swap the global :default :logger handler's
|
|
# formatter and forward its output to a self()-bound IO device so the
|
|
# test can capture the JSON-encoded output. Restored on exit.
|
|
#
|
|
# Opts out of the suite-wide capture_log flag — capture_log hot-swaps
|
|
# the :default handler for its own capture handler, so our direct
|
|
# :logger.get_handler_config(:default) lookup in setup would 404.
|
|
use ExUnit.Case, async: false
|
|
|
|
alias LoggerJSON.Formatters.Basic
|
|
|
|
require Logger
|
|
|
|
@moduletag capture_log: false
|
|
|
|
describe "structured JSON formatter" do
|
|
setup do
|
|
{:ok, handler_cfg} = :logger.get_handler_config(:default)
|
|
prev_formatter = handler_cfg.formatter
|
|
|
|
new_formatter =
|
|
Basic.new(metadata: [:request_id, :trace_id, :worker, :queue, :job_id])
|
|
|
|
:ok = :logger.update_handler_config(:default, :formatter, new_formatter)
|
|
|
|
on_exit(fn ->
|
|
:logger.update_handler_config(:default, :formatter, prev_formatter)
|
|
end)
|
|
|
|
{:ok, formatter: new_formatter}
|
|
end
|
|
|
|
test "Basic formatter encodes an info log as a valid JSON object",
|
|
%{formatter: {formatter_mod, formatter_cfg}} do
|
|
# Build a `:logger` log event the same shape the handler feeds the
|
|
# formatter, then assert the formatter's output is valid JSON with
|
|
# the expected message and metadata fields.
|
|
log_event = %{
|
|
level: :info,
|
|
msg: {:string, "hello-json"},
|
|
meta: %{
|
|
time: :os.system_time(:microsecond),
|
|
request_id: "abc-123",
|
|
worker: "TestWorker"
|
|
}
|
|
}
|
|
|
|
rendered = formatter_mod.format(log_event, formatter_cfg)
|
|
payload = rendered |> IO.iodata_to_binary() |> String.trim_trailing("\n")
|
|
|
|
assert {:ok, decoded} = Jason.decode(payload)
|
|
assert decoded["message"] == "hello-json"
|
|
assert get_in(decoded, ["metadata", "request_id"]) == "abc-123"
|
|
assert get_in(decoded, ["metadata", "worker"]) == "TestWorker"
|
|
end
|
|
|
|
test "swapping the :default handler formatter takes effect" do
|
|
# Smoke test that the setup actually attached our JSON formatter
|
|
# to the :default handler (i.e. the runtime.exs swap would land).
|
|
{:ok, cfg} = :logger.get_handler_config(:default)
|
|
assert match?({Basic, _}, cfg.formatter)
|
|
end
|
|
end
|
|
end
|