From 602bcc57a135d3364fcb462f93c886740b035bb9 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:56:29 -0300 Subject: [PATCH] wip poc multiple towers --- lib/tower.ex | 11 ++++---- lib/tower/bandit_exception_handler.ex | 10 +++---- lib/tower/ephemeral_reporter.ex | 4 +-- lib/tower/logger_handler.ex | 10 +++---- lib/tower/oban_exception_handler.ex | 10 +++---- test/tower_multiple_test.exs | 39 +++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 test/tower_multiple_test.exs diff --git a/lib/tower.ex b/lib/tower.ex index cea705c..658cc27 100644 --- a/lib/tower.ex +++ b/lib/tower.ex @@ -264,11 +264,12 @@ defmodule Tower do Note that `Tower.attach/0` is not a precondition for `Tower` `handle_*` functions to work properly and inform reporters. They are independent. """ - @spec attach() :: :ok - def attach do - :ok = Tower.LoggerHandler.attach() - :ok = Tower.BanditExceptionHandler.attach() - :ok = Tower.ObanExceptionHandler.attach() + @spec attach(atom()) :: :ok + def attach(opts \\ []) do + {:ok, config} = Tower.Config.from_opts(opts) + :ok = Tower.LoggerHandler.attach(Module.concat(name, :LoggerHandler)) + :ok = Tower.BanditExceptionHandler.attach(Module.concat(name, :BanditExceptionHandler)) + :ok = Tower.ObanExceptionHandler.attach(Module.concat(name, :ObanExceptionHandler)) end @doc """ diff --git a/lib/tower/bandit_exception_handler.ex b/lib/tower/bandit_exception_handler.ex index 864e805..5f5d86c 100644 --- a/lib/tower/bandit_exception_handler.ex +++ b/lib/tower/bandit_exception_handler.ex @@ -3,19 +3,19 @@ defmodule Tower.BanditExceptionHandler do require Logger - @handler_id __MODULE__ + @default_handler_id __MODULE__ - def attach do + def attach(handler_id \\ @default_handler_id) do :telemetry.attach( - @handler_id, + handler_id, [:bandit, :request, :exception], &__MODULE__.handle_event/4, _handler_config = [] ) end - def detach do - :telemetry.detach(@handler_id) + def detach(handler_id \\ @default_handler_id) do + :telemetry.detach(handler_id) end def handle_event( diff --git a/lib/tower/ephemeral_reporter.ex b/lib/tower/ephemeral_reporter.ex index 1da3094..20689ff 100644 --- a/lib/tower/ephemeral_reporter.ex +++ b/lib/tower/ephemeral_reporter.ex @@ -52,7 +52,7 @@ defmodule Tower.EphemeralReporter do Returns the list of all stored events. """ @spec events() :: [Tower.Event.t()] - def events do - Agent.get(__MODULE__, & &1) + def events(agent \\ __MODULE__) do + Agent.get(agent, & &1) end end diff --git a/lib/tower/logger_handler.ex b/lib/tower/logger_handler.ex index 1edefce..f5e4d79 100644 --- a/lib/tower/logger_handler.ex +++ b/lib/tower/logger_handler.ex @@ -1,15 +1,15 @@ defmodule Tower.LoggerHandler do @moduledoc false - @handler_id Tower + @default_handler_id __MODULE__ @own_logs_domain [:tower, :logger_handler] require Logger @spec attach() :: :ok | {:error, term()} - def attach do + def attach(handler_id \\ @default_handler_id) do :logger.add_handler( - @handler_id, + handler_id, __MODULE__, %{ level: :all, @@ -24,8 +24,8 @@ defmodule Tower.LoggerHandler do end @spec detach() :: :ok | {:error, term()} - def detach do - :logger.remove_handler(@handler_id) + def detach(handler_id \\ @default_handler_id) do + :logger.remove_handler(handler_id) end # :logger callbacks diff --git a/lib/tower/oban_exception_handler.ex b/lib/tower/oban_exception_handler.ex index b238eef..8282904 100644 --- a/lib/tower/oban_exception_handler.ex +++ b/lib/tower/oban_exception_handler.ex @@ -3,19 +3,19 @@ defmodule Tower.ObanExceptionHandler do require Logger - @handler_id __MODULE__ + @default_handler_id __MODULE__ - def attach do + def attach(handler_id \\ @default_handler_id) do :telemetry.attach( - @handler_id, + handler_id, [:oban, :job, :exception], &__MODULE__.handle_event/4, _handler_config = [] ) end - def detach do - :telemetry.detach(@handler_id) + def detach(handler_id \\ @default_handler_id) do + :telemetry.detach(handler_id) end def handle_event( diff --git a/test/tower_multiple_test.exs b/test/tower_multiple_test.exs new file mode 100644 index 0000000..e5e7fbf --- /dev/null +++ b/test/tower_multiple_test.exs @@ -0,0 +1,39 @@ +defmodule TowerMultipleTest do + use ExUnit.Case + + # use AssertEventually, timeout: 100, interval: 10 + + # import ExUnit.CaptureLog, only: [capture_log: 1] + + test "multiple towers" do + {:ok, ephemeral_reporter_1} = Tower.EphemeralReporter.start_link([]) + {:ok, ephemeral_reporter_2} = Tower.EphemeralReporter.start_link([]) + + assert [] = Tower.EphemeralReporter.events(ephemeral_reporter_1) + assert [] = Tower.EphemeralReporter.events(ephemeral_reporter_2) + + spawn(fn -> 1 / 0 end) + Process.sleep(200) + + assert [] = Tower.EphemeralReporter.events(ephemeral_reporter_1) + assert [] = Tower.EphemeralReporter.events(ephemeral_reporter_2) + + Tower.attach(Tower1, reporters: [{Tower.EphemeralReporter, ephemeral_reporter_1}]) + Tower.attach(Tower2, reporters: [{Tower.EphemeralReporter, ephemeral_reporter_2}]) + + spawn(fn -> 1 / 0 end) + Process.sleep(200) + + assert [_event] = Tower.EphemeralReporter.events(ephemeral_reporter_1) + assert [_event] = Tower.EphemeralReporter.events(ephemeral_reporter_2) + + :ok = Tower.detach(Tower1) + + spawn(fn -> 1 / 0 end) + Process.sleep(200) + + assert [_event] = Tower.EphemeralReporter.events(ephemeral_reporter_1) + assert [_event1, _event2] = Tower.EphemeralReporter.events(ephemeral_reporter_2) + # :ok = Tower.EphemeralReporter.stop(ephemeral_reporter_1) + end +end