HTTPoison

This feature requires AppSignal for Elixir version 2.17.0 or higher.
This feature requires HTTPoison version 2.0.0 or higher.

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:

Do not use alias Appsignal.HTTPoison. This would shadow the HTTPoison module name, causing %HTTPoison.Response{} and %HTTPoison.Error{} pattern matches to fail.

Elixir
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:

Elixir
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:

Elixir
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