HTTPoison
The AppSignal for Elixir package instruments HTTP requests performed by HTTPoison.
HTTPoison is a popular HTTP client for Elixir. Unlike Finch and Tesla, HTTPoison does not emit telemetry events, so AppSignal cannot automatically instrument it. Instead, AppSignal provides wrapper modules that you opt into: Appsignal.HTTPoison as a drop-in client, and Appsignal.HTTPoison.Base for custom client modules. The response and error structs (%HTTPoison.Response{}, %HTTPoison.Error{}, ...) are HTTPoison's own types and are returned unchanged.
AppSignal will wrap requests executed via Appsignal.HTTPoison as request.httpoison events on your performance samples' event timeline, allowing you to see how much time HTTPoison spends making external API requests. This data may help inform you to move the API requests to a background job, or to introduce caching to help speed up performance and limit unnecessary API requests.
Configuration
HTTPoison instrumentation is opt-in. Choose the approach that best fits your application.
Using Appsignal.HTTPoison directly
Call Appsignal.HTTPoison instead of HTTPoison to make instrumented requests. Pattern-match on %HTTPoison.Response{...} and %HTTPoison.Error{...} as normal — these are HTTPoison's own struct types, returned unchanged:
defmodule MyAppWeb.PageController do use MyAppWeb, :controller def index(conn, _params) do case Appsignal.HTTPoison.get("https://api.example.com/users") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> render(conn, :index, users: body) {:ok, %HTTPoison.Response{status_code: status}} -> conn |> put_status(status) |> text("Error") {:error, %HTTPoison.Error{reason: reason}} -> conn |> put_status(500) |> text("Error: #{reason}") end end end
Custom client modules
If you use a custom HTTP client module based on HTTPoison.Base, replace use HTTPoison.Base with use Appsignal.HTTPoison.Base. No further changes are needed — inside the module, you can call methods like get/1 and post/3, and match on HTTPoison's response and error structs as normal:
defmodule MyApp.ApiClient do # replace `use HTTPoison.Base` with `use Appsignal.HTTPoison.Base` use Appsignal.HTTPoison.Base def process_url(url) do "https://api.example.com" <> url end def users do case get("/users") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, body} {:ok, %HTTPoison.Response{status_code: status}} -> {:error, status} {:error, %HTTPoison.Error{reason: reason}} -> {:error, reason} end end end
All requests made through your custom client will then be instrumented automatically. If your module overrides request/5, make sure to call super to preserve the instrumentation:
defmodule MyApp.ApiClient do use Appsignal.HTTPoison.Base def request(method, url, body, headers, options) do # ... custom logic here ... super(method, url, body, headers, options) end end