mirror of
https://github.com/TheRealOwenRees/plantid-discord-bot.git
synced 2026-07-22 20:16:57 +00:00
Discord customer logger
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
defmodule PlantIdDiscordBot.DiscordLogger do
|
||||
require Logger
|
||||
use Tesla
|
||||
|
||||
plug(Tesla.Middleware.JSON)
|
||||
|
||||
@behaviour :gen_event
|
||||
|
||||
def init({__MODULE__, name}) do
|
||||
{:ok, configure(name, [])}
|
||||
end
|
||||
|
||||
def handle_call({:configure, opts}, %{name: name} = state) do
|
||||
{:ok, :ok, configure(name, opts, state)}
|
||||
end
|
||||
|
||||
def handle_event({_level, gl, {Logger, _, _, _}}, state) when node(gl) != node() do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_event({level, _gl, {Logger, msg, ts, md}}, %{} = state) do
|
||||
if is_level_okay(level, state.level) do
|
||||
log_to_discord(state.webhook_url, level, msg, ts, md)
|
||||
end
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_event(:flush, state) do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_info(_, state) do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
defp is_level_okay(lvl, min_level) do
|
||||
is_nil(min_level) or Logger.compare_levels(lvl, min_level) != :lt
|
||||
end
|
||||
|
||||
def log_to_discord(webhook_url, level, msg, ts, md) do
|
||||
formatted_msg = format_message(level, msg, ts, md)
|
||||
body = %{content: formatted_msg}
|
||||
|
||||
post(webhook_url, body)
|
||||
|> case do
|
||||
{:ok, %{status: status}} when status in 200..299 -> :ok
|
||||
{:error, reason} -> Logger.error("Error sending log to Discord: #{inspect(reason)}")
|
||||
_any -> Logger.error("Error sending log to Discord")
|
||||
end
|
||||
end
|
||||
|
||||
def format_message(level, msg, _ts, md) do
|
||||
timestamp = DateTime.utc_now()
|
||||
source = md[:application]
|
||||
msg = IO.iodata_to_binary(msg) |> String.slice(0..1900)
|
||||
|
||||
"[#{timestamp}] [#{source}] [#{level}] `#{msg}`"
|
||||
end
|
||||
|
||||
defp configure(name, opts) do
|
||||
state = %{name: name, format: nil, level: nil, metadata: nil, metadata_filter: nil}
|
||||
configure(name, opts, state)
|
||||
end
|
||||
|
||||
defp configure(name, opts, state) do
|
||||
env = Application.get_env(:logger, name, [])
|
||||
opts = Keyword.merge(env, opts)
|
||||
Application.put_env(:logger, name, opts)
|
||||
|
||||
new_state = %{
|
||||
webhook_url: Keyword.get(opts, :webhook_url, nil),
|
||||
level: Keyword.get(opts, :level)
|
||||
}
|
||||
|
||||
Map.merge(state, new_state)
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@ defmodule PlantIdDiscordBot.Consumer do
|
||||
@moduledoc """
|
||||
A Discord bot that identifies plants from photos of their organs.
|
||||
"""
|
||||
|
||||
use Nostrum.Consumer
|
||||
alias Nostrum.Api
|
||||
alias PlantIdDiscordBot.Cog
|
||||
|
||||
@@ -3,6 +3,8 @@ defmodule PlantIdDiscordBot.Cog.Info do
|
||||
import Nostrum.Struct.Embed
|
||||
alias PlantIdDiscordBot.Utils
|
||||
|
||||
require Logger
|
||||
|
||||
# reference to Nostrum.Api in non-test environments, reference to mock in test
|
||||
@api Application.compile_env(:plantid_discord_bot, :api)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
defmodule PlantIdDiscordBot.Cog.PlantNet do
|
||||
require Logger
|
||||
use Nostrum.Consumer
|
||||
alias PlantIdDiscordBot.RateLimiter
|
||||
alias PlantIdDiscordBot.PlantNet.Parser
|
||||
@@ -50,7 +51,7 @@ defmodule PlantIdDiscordBot.Cog.PlantNet do
|
||||
})
|
||||
end
|
||||
|
||||
IO.inspect(saved_images)
|
||||
Logger.debug(saved_images)
|
||||
|
||||
# TODO use actual image data
|
||||
image1 =
|
||||
@@ -73,13 +74,13 @@ defmodule PlantIdDiscordBot.Cog.PlantNet do
|
||||
})
|
||||
|
||||
{:ok, %HTTPoison.Response{status_code: 400}} ->
|
||||
# TODO add logger
|
||||
Logger.error("Malformed request sent to the PlantNet API")
|
||||
|
||||
Api.create_followup_message(interaction.application_id, interaction.token, %{
|
||||
content: "Bad Request"
|
||||
})
|
||||
|
||||
{:ok, %HTTPoison.Response{status_code: 404}} ->
|
||||
# TODO add logger
|
||||
RateLimiter.increase_counter(interaction.guild_id)
|
||||
|
||||
Api.create_followup_message(interaction.application_id, interaction.token, %{
|
||||
@@ -87,19 +88,20 @@ defmodule PlantIdDiscordBot.Cog.PlantNet do
|
||||
})
|
||||
|
||||
{:ok, %HTTPoison.Response{status_code: 429}} ->
|
||||
# TODO add logger
|
||||
Logger.warning("Request limit exceeded for the PlantNet API")
|
||||
|
||||
Api.create_followup_message(interaction.application_id, interaction.token, %{
|
||||
content: "Too Many Requests"
|
||||
})
|
||||
|
||||
{_, _} ->
|
||||
# TODO add logger
|
||||
Logger.error("Internal server error when contacting the PlantNet API")
|
||||
|
||||
Api.create_followup_message(interaction.application_id, interaction.token, %{
|
||||
content: "Internal Server Error"
|
||||
})
|
||||
end
|
||||
|
||||
# TODO make into a task for async deletion, deal with errors
|
||||
Enum.map(saved_images, fn {:ok, filename} -> filename end)
|
||||
|> File.delete_files!()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user