Packages

appsignal

2.15.6
2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.0 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.1 2.14.0 2.13.4 2.13.3 2.13.2 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 2.12.0 2.11.0 2.10.2 2.10.1 2.10.0 2.9.2 2.9.1 2.9.0 2.8.3 2.8.2 2.8.1 2.8.0 2.7.13 2.7.12 2.7.11 2.7.10 2.7.9 2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 2.7.3 2.7.2 2.7.1 2.7.0 2.7.0-beta.1 2.6.1 2.6.0 2.5.3 2.5.2 2.5.1 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.1 2.3.0 2.2.19 2.2.18 2.2.17 2.2.16 2.2.15 2.2.14 2.2.13 2.2.12 retired 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.15 2.1.14 2.1.13 2.1.12 2.1.11 2.1.10 2.1.9 2.1.8 2.1.7 2.1.7-beta.1 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.8 2.0.7 2.0.6 2.0.6-beta.1 2.0.5 retired 2.0.4 retired 2.0.3 retired 2.0.2 retired 2.0.1 retired 2.0.0 retired 2.0.0-beta.11 2.0.0-beta.10 2.0.0-beta.9 2.0.0-beta.8 2.0.0-beta.7 2.0.0-beta.6 2.0.0-beta.5 2.0.0-beta.4 2.0.0-beta.3 2.0.0-beta.2 2.0.0-beta.1 2.0.0-alpha.7 2.0.0-alpha.6 2.0.0-alpha.5 2.0.0-alpha.4 2.0.0-alpha.3 2.0.0-alpha.2 2.0.0-alpha.1 1.13.5 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.13.0-beta.2 1.13.0-beta.1 1.12.1 1.12.0 1.12.0-beta.3 1.12.0-beta.2 1.12.0-beta.1 1.11.8 1.11.7 1.11.6 1.11.5 1.11.4 1.11.3 1.11.2 1.11.1 1.11.0 1.11.0-beta.1 1.10.13 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.4 1.9.3 1.9.2 1.9.1 1.9.1-beta.1 1.9.0 1.9.0-beta.1 1.9.0-alpha.1 1.8.2 1.8.1 1.8.1-beta.2 1.8.1-beta.1 1.8.0 1.7.2 1.7.1 1.7.0 1.7.0-beta.2 1.7.0-beta.1 1.7.0-alpha.4 1.7.0-alpha.3 1.7.0-alpha.2 1.7.0-alpha.1 1.6.7 1.6.6 1.6.6-beta.2 1.6.6-beta.1 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.6.0-beta.1 1.6.0-alpha.1 1.5.1 1.5.0 1.5.0-beta.2 1.5.0-beta.1 1.4.11-beta.1 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.4.0-alpha.1 1.3.6 1.3.6-beta.1 1.3.5 1.3.4 1.3.4-beta.1 1.3.3 1.3.2 1.3.1 1.3.0 1.3.0-beta.3 1.3.0-beta.2 1.3.0-beta.1 1.2.3 1.2.2 1.2.1 1.2.0 1.1.1 1.1.0 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 1.0.0-rc.1 0.13.0 0.12.3 0.12.2 0.12.1 0.12.0 0.11.6 0.11.5 0.11.4 0.11.3 0.11.2 0.11.1 0.11.0 0.10.0 0.9.2 0.9.1 0.9.0 0.8.0 0.7.1 0.7.0 0.6.2 0.6.1 0.6.0 0.5.0 0.4.0 0.3.0 0.2.0 0.1.0 0.0.9 0.0.8 0.0.7 0.0.6 0.0.5 0.0.4 0.0.3 0.0.2 0.0.1

Collects error and performance data from your Elixir applications and sends it to AppSignal

Current section

Files

Jump to
appsignal lib appsignal finch.ex
Raw

lib/appsignal/finch.ex

defmodule Appsignal.Finch do
require Logger
@tracer Application.compile_env(:appsignal, :appsignal_tracer, Appsignal.Tracer)
@span Application.compile_env(:appsignal, :appsignal_span, Appsignal.Span)
@moduledoc false
def attach do
handlers = %{
[:finch, :request, :start] => &__MODULE__.finch_request_start/4,
[:finch, :request, :stop] => &__MODULE__.finch_request_stop/4,
[:finch, :request, :exception] => &__MODULE__.finch_request_stop/4
}
for {event, fun} <- handlers do
case :telemetry.attach({__MODULE__, event}, event, fun, :ok) do
:ok ->
_ = Appsignal.IntegrationLogger.debug("Appsignal.Finch attached to #{inspect(event)}")
:ok
{:error, _} = error ->
Logger.warning("Appsignal.Finch not attached to #{inspect(event)}: #{inspect(error)}")
error
end
end
end
def finch_request_start(
_event,
_measurements,
%{name: name, request: request},
_config
) do
if !has_prefix(name, "AppsignalFinch") do
do_finch_request_start(@tracer.current_span(), name, request)
end
end
def finch_request_start(_event, _measurements, _metadata, _config) do
# In Finch versions 0.11 and below, the `request` events for `start` and
# `stop` (but not `exception`) are also emitted, but the events' meaning is
# different, and the metadata object provided does not contain a `request`
# key.
# The implementations of the event handling functions above this perform
# pattern matching on the presence of the `request` key, as a way to
# check that the event shape is correct, meaning that the event is from
# Finch version 0.12 or above.
# The nil-returning catch-all implementations of these functions exist to
# catch events emitted by Finch versions below 0.12 and do nothing,
# ensuring that a `FunctionClauseError` is not raised.
nil
end
defp do_finch_request_start(nil, _name, _request), do: nil
defp do_finch_request_start(parent, _name, request) do
uri = %URI{scheme: Atom.to_string(request.scheme), host: request.host, port: request.port}
"http_request"
|> @tracer.create_span(parent)
|> @span.set_name("#{request.method} #{URI.to_string(uri)}")
|> @span.set_attribute("appsignal:category", "request.finch")
end
def finch_request_stop(_event, _measurements, %{name: name, request: _request}, _config) do
if !has_prefix(name, "AppsignalFinch") do
if span = @tracer.current_span() do
@tracer.close_span(span)
end
end
end
def finch_request_stop(_event, _measurements, _metadata, _config) do
nil
end
defp has_prefix(name, prefix) when is_atom(name) do
atom_string = Atom.to_string(name)
if String.starts_with?(atom_string, "Elixir.") do
module_name = String.replace_prefix(atom_string, "Elixir.", "")
String.starts_with?(module_name, prefix)
else
String.starts_with?(atom_string, prefix)
end
end
defp has_prefix(name, prefix) when is_binary(name) do
name
|> String.starts_with?(prefix)
end
end