Skip to content

Commit

Permalink
feat: reporter (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
grzuy authored Jun 12, 2024
1 parent 9f2e2d7 commit c3c5fa0
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 3 deletions.
39 changes: 39 additions & 0 deletions lib/tower_honeybadger/honeybadger/client.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule TowerHoneybadger.Honeybadger.Client do
@base_url "https://api.honeybadger.io/v1"
@api_key_header ~c"X-API-Key"

def post(path, payload) when is_map(payload) do
case :httpc.request(
:post,
{
~c"#{@base_url}#{path}",
[{@api_key_header, api_key()}],
~c"application/json",
Jason.encode!(payload)
},
[
ssl: [
verify: :verify_peer,
cacerts: :public_key.cacerts_get(),
# Support wildcard certificates
customize_hostname_check: [
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
]
]
],
[]
) do
{:ok, result} ->
result
|> IO.inspect()

{:error, reason} ->
reason
|> IO.inspect()
end
end

defp api_key do
Application.fetch_env!(:tower_honeybadger, :api_key)
end
end
65 changes: 65 additions & 0 deletions lib/tower_honeybadger/honeybadger/notice.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule TowerHoneybadger.Honeybadger.Notice do
def from_exception(exception, stacktrace, options \\ [])
when is_exception(exception) and is_list(stacktrace) do
plug_conn = Keyword.get(options, :plug_conn)

%{
"error" => %{
"class" => inspect(exception.__struct__),
"message" => Exception.message(exception),
"backtrace" => backtrace(stacktrace)
},
"server" => %{
"environment_name" => environment()
}
}
|> maybe_put_request_data(plug_conn)
end

defp backtrace(stacktrace) do
stacktrace
|> Enum.map(fn {m, f, a, location} ->
backtrace_entry = %{
"method" => Exception.format_mfa(m, f, a)
}

backtrace_entry =
if location[:file] do
Map.put(backtrace_entry, "file", to_string(location[:file]))
else
backtrace_entry
end

if location[:line] do
Map.put(backtrace_entry, "number", location[:line])
else
backtrace_entry
end
end)
end

defp maybe_put_request_data(notice, %Plug.Conn{} = conn) do
notice
|> Map.put("request", request_data(conn))
end

defp request_data(%Plug.Conn{} = conn) do
conn =
conn
|> Plug.Conn.fetch_cookies()
|> Plug.Conn.fetch_query_params()

%{
"url" => "#{conn.scheme}://#{conn.host}:#{conn.port}#{conn.request_path}",
"params" =>
case conn.params do
%Plug.Conn.Unfetched{aspect: :params} -> "unfetched"
other -> other
end
}
end

defp environment do
Application.fetch_env!(:tower_honeybadge, :environment)
end
end
30 changes: 30 additions & 0 deletions lib/tower_honeybadger/reporter.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule TowerHoneybadger.Reporter do
@behaviour Tower.Reporter

alias TowerHoneybadger.Honeybadger

@impl true
def report_exception(exception, stacktrace, metadata \\ %{})
when is_exception(exception) and is_list(stacktrace) do
if enabled?() do
Honeybadger.Client.post(
"/notices",
Honeybadger.Notice.from_exception(exception, stacktrace, plug_conn: plug_conn(metadata))
)
else
IO.puts("TowerHoneybadger NOT enabled, ignoring exception report...")
end
end

defp plug_conn(%{conn: conn}) do
conn
end

defp plug_conn(_) do
nil
end

defp enabled? do
Application.get_env(:tower_honeybadger, :enabled, false)
end
end
7 changes: 4 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ defmodule TowerHoneybadger.MixProject do
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
extra_applications: [:logger, :public_key]
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
{:jason, "~> 1.4"},
{:tower, github: "mimiquate/tower"},
{:plug, "~> 1.16"}
]
end
end
8 changes: 8 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%{
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"plug": {:hex, :plug, "1.16.0", "1d07d50cb9bb05097fdf187b31cf087c7297aafc3fed8299aac79c128a707e47", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cbf53aa1f5c4d758a7559c0bd6d59e286c2be0c6a1fac8cc3eee2f638243b93e"},
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"tower": {:git, "https://github.com/mimiquate/tower.git", "140a358d321ede1f3f2225341430143c2ec47d47", []},
}

0 comments on commit c3c5fa0

Please sign in to comment.