From fee88bdcfba2b7324af17ec61614b9c4b1342dd6 Mon Sep 17 00:00:00 2001 From: Aleksei Matiushkin Date: Sat, 30 Nov 2024 07:09:18 +0100 Subject: [PATCH] `messenger_channels` --- config/config.exs | 2 +- lib/options.ex | 5 ----- lib/telemetria.ex | 11 +++++++---- lib/telemetria/messenger.ex | 5 +++-- lib/telemetria/messenger/logger.ex | 18 ++++++++++++++++++ lib/telemetria/messenger/slack.ex | 4 +--- lib/telemetria/throttler.ex | 20 ++++---------------- test/support/telemetria_tester.ex | 2 +- 8 files changed, 35 insertions(+), 32 deletions(-) create mode 100644 lib/telemetria/messenger/logger.ex diff --git a/config/config.exs b/config/config.exs index ba672a2..659f465 100644 --- a/config/config.exs +++ b/config/config.exs @@ -24,5 +24,5 @@ config :telemetria, # metadata: :all if Mix.env() == :test do - config :telemetria, :messenger, :mox + config :telemetria, :messenger_channels, %{mox: {:mox, []}} end diff --git a/lib/options.ex b/lib/options.ex index 33ed4eb..4fbd992 100644 --- a/lib/options.ex +++ b/lib/options.ex @@ -52,11 +52,6 @@ defmodule Telemetria.Options do doc: "The backend to be used as an actual implementation", default: Telemetria.Backend.Telemetry ], - messenger: [ - type: :atom, - doc: "The messenger to be used as an actual implementation", - default: nil - ], messenger_channels: [ type: :map, doc: "The messenger channels as a map `%{name => {impl, opts}}`", diff --git a/lib/telemetria.ex b/lib/telemetria.ex index 8a07094..f7d89e3 100644 --- a/lib/telemetria.ex +++ b/lib/telemetria.ex @@ -38,8 +38,9 @@ defmodule Telemetria do - **`reshape: (map() -> map())`** — the function to be called on the resulting attributes to reshape them before sending to the actual telemetry handler; the default application-wide reshaper might be set in `:telemetria, :reshaper` config - - **`messenger: true | false | module()`** — when `true` or `module`, the instant message - is to be sent to the desired destination (like slack) + - **`messenger_channels: %{optional(atom()) => {module, keyword()}`** — more handy messenger + management, several channels config with channels names associated with their + implementations and properties ### Example @@ -427,8 +428,10 @@ defmodule Telemetria do defp variablize({var, _, _} = val), do: {var, val} defp get_channel_info(channel, level) do - {mod, opts} = Map.get(@messenger_channels, channel, {channel, []}) - {mod, Keyword.put(opts, :level, level)} + case Map.get(@messenger_channels, channel, {channel, []}) do + {mod, opts} -> {mod, Keyword.put(opts, :level, level)} + mod when is_atom(mod) -> {mod, level: level} + end end defp extract_guards([]), do: [] diff --git a/lib/telemetria/messenger.ex b/lib/telemetria/messenger.ex index b4fbe0b..708f9a7 100644 --- a/lib/telemetria/messenger.ex +++ b/lib/telemetria/messenger.ex @@ -25,7 +25,7 @@ defmodule Telemetria.Messenger do @optional_callbacks format: 2 - @implementation Application.compile_env(:telemetria, :messenger, Logger) + @implementation Telemetria.Messenger.Logger @doc "Routes the message to the configured messenger(s)" @spec post(message() | String.t(), impl :: atom() | module(), opts :: keyword()) :: @@ -43,7 +43,8 @@ defmodule Telemetria.Messenger do do_post(message, impl, opts) end - def post(message, impl, opts), do: do_post(message, impl, opts) + def post(message, impl, opts) when is_binary(message), + do: do_post(message, impl, opts) defp do_post(message, impl, opts) do impl = fix_impl_name(impl) diff --git a/lib/telemetria/messenger/logger.ex b/lib/telemetria/messenger/logger.ex new file mode 100644 index 0000000..ed4e3f9 --- /dev/null +++ b/lib/telemetria/messenger/logger.ex @@ -0,0 +1,18 @@ +defmodule Telemetria.Messenger.Logger do + @moduledoc false + + require Logger + + @behaviour Telemetria.Messenger + + @impl true + def format(message, opts), do: inspect(message, opts) + + Enum.each(~w|debug info warning error|a, fn level -> + @impl true + def unquote(level)(message, opts), + do: post(unquote(level), message, opts) + end) + + defp post(level, message, opts), do: {Logger.log(level, message), opts} +end diff --git a/lib/telemetria/messenger/slack.ex b/lib/telemetria/messenger/slack.ex index 0aad528..ba20aad 100644 --- a/lib/telemetria/messenger/slack.ex +++ b/lib/telemetria/messenger/slack.ex @@ -3,8 +3,6 @@ defmodule Telemetria.Messenger.Slack do @behaviour Telemetria.Messenger - @default_url Application.compile_env(:telemetria, :messenger_default_url) - @impl true # %{ # args: [a: 42], @@ -89,7 +87,7 @@ defmodule Telemetria.Messenger.Slack do |> Jason.encode!() |> :erlang.binary_to_list() - url = Keyword.get(opts, :url, @default_url) + url = Keyword.fetch!(opts, :url) :httpc.request(:post, {to_charlist(url), [], ~c"application/json", json}, [], []) end diff --git a/lib/telemetria/throttler.ex b/lib/telemetria/throttler.ex index 89d5475..1130766 100644 --- a/lib/telemetria/throttler.ex +++ b/lib/telemetria/throttler.ex @@ -74,22 +74,10 @@ defmodule Telemetria.Throttler do |> Map.put(:measurements, measurements) |> Map.pop(:context, %{}) - case messenger do - false -> - :ok - - nil -> - :ok - - impl when is_atom(impl) -> - updates - |> Map.put(:event, event) - |> Telemetria.Messenger.post(impl) - - {impl, opts} when is_atom(impl) -> - updates - |> Map.put(:event, event) - |> Telemetria.Messenger.post(impl, opts) + with {impl, opts} when is_atom(impl) and is_list(opts) <- messenger do + updates + |> Map.put(:event, event) + |> Telemetria.Messenger.post(impl, opts) end updates = if is_function(reshaper, 1), do: reshaper.(updates), else: updates diff --git a/test/support/telemetria_tester.ex b/test/support/telemetria_tester.ex index fb6e5d0..215be0b 100644 --- a/test/support/telemetria_tester.ex +++ b/test/support/telemetria_tester.ex @@ -33,7 +33,7 @@ defmodule Test.Telemetria.Example do t(&(&1 / 2), suffix: :foo).(a) end - @telemetria level: :warning, messenger: true, locals: [:result] + @telemetria level: :warning, messenger: :mox, locals: [:result] def third(a) do result = a / 3 result