Current section

Files

Jump to
disco_log lib disco_log.ex
Raw

lib/disco_log.ex

defmodule DiscoLog do
@moduledoc """
Elixir-based built-in error tracking solution.
"""
alias DiscoLog.Error
alias DiscoLog.Config
alias DiscoLog.Context
alias DiscoLog.Storage
alias DiscoLog.Discord.API
alias DiscoLog.Discord.Prepare
@spec report(Exception.kind(), any(), Exception.stacktrace(), Context.t(), Config.t() | nil) ::
API.response()
def report(kind, reason, stacktrace, context \\ %{}, config \\ nil) do
config = maybe_read_config(config)
context = Map.merge(DiscoLog.Context.get(), context)
error = Error.new(kind, reason, stacktrace) |> Error.enrich(config)
log_occurrence(error, context, config)
end
@doc false
def log_occurrence(error, context, config) do
config.supervisor_name
|> Storage.get_thread_id(error.fingerprint)
|> case do
nil ->
available_tags = Storage.get_tags(config.supervisor_name) || %{}
applied_tags =
context
|> Map.keys()
|> Enum.filter(&(&1 in Map.keys(available_tags)))
|> Enum.map(&Map.fetch!(available_tags, &1))
message =
Prepare.prepare_occurrence(error, context, applied_tags)
with {:ok, %{status: 201, body: %{"id" => thread_id}}} = response <-
API.post_thread(config.discord_client, config.occurrences_channel_id, message) do
Storage.add_thread_id(config.supervisor_name, error.fingerprint, thread_id)
response
end
thread_id ->
message = Prepare.prepare_occurrence_message(error, context)
API.post_message(config.discord_client, thread_id, message)
end
end
@spec log_info(String.t(), Context.t(), Config.t() | nil) :: API.response()
def log_info(message, context \\ %{}, config \\ nil) do
config = maybe_read_config(config)
message = Prepare.prepare_message(message, context)
API.post_message(config.discord_client, config.info_channel_id, message)
end
@spec log_error(String.t(), Context.t(), Config.t() | nil) :: API.response()
def log_error(message, context \\ %{}, config \\ nil) do
config = maybe_read_config(config)
message = Prepare.prepare_message(message, context)
API.post_message(config.discord_client, config.error_channel_id, message)
end
defp maybe_read_config(nil), do: DiscoLog.Config.read!()
defp maybe_read_config(config), do: config
end