Le paquet AppSignal pour Elixir instrumente les requêtes HTTP effectuées par HTTPoison.
HTTPoison est un client HTTP populaire pour Elixir. Contrairement à Finch et Tesla, HTTPoison n’émet pas d’événements de télémétrie, donc AppSignal ne peut pas l’instrumenter automatiquement. À la place, AppSignal fournit des modules wrappers que vous activez explicitement : Appsignal.HTTPoison comme client drop-in, et Appsignal.HTTPoison.Base pour les modules clients personnalisés. Les structs de réponse et d’erreur (%HTTPoison.Response{}, %HTTPoison.Error{}, …) sont les types propres à HTTPoison et sont renvoyés inchangés.
AppSignal enveloppera les requêtes exécutées via Appsignal.HTTPoison en tant qu’événements request.httpoison sur la timeline des événements de vos échantillons de performance, vous permettant de voir combien de temps HTTPoison passe à effectuer des requêtes API externes. Ces données peuvent vous aider à décider de déplacer les requêtes API vers un job en arrière-plan, ou à introduire de la mise en cache pour aider à accélérer les performances et limiter les requêtes API inutiles.
Configuration
L’instrumentation HTTPoison est en opt-in. Choisissez l’approche qui correspond le mieux à votre application.
Utiliser Appsignal.HTTPoison directement
Appelez Appsignal.HTTPoison au lieu de HTTPoison pour effectuer des requêtes instrumentées. Pattern-matchez sur %HTTPoison.Response{...} et %HTTPoison.Error{...} comme d’habitude — ce sont les types de structs propres à HTTPoison, renvoyés inchangés :
N’utilisez pas alias Appsignal.HTTPoison. Cela masquerait le nom du module
HTTPoison, ce qui ferait échouer les pattern-matchings sur %HTTPoison.Response{} et
%HTTPoison.Error{}.
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
Modules clients personnalisés
Si vous utilisez un module client HTTP personnalisé basé sur HTTPoison.Base, remplacez use HTTPoison.Base par use Appsignal.HTTPoison.Base. Aucune autre modification n’est nécessaire — à l’intérieur du module, vous pouvez appeler des méthodes comme get/1 et post/3, et faire correspondre les structs de réponse et d’erreur HTTPoison comme d’habitude :
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
Toutes les requêtes effectuées via votre client personnalisé seront alors instrumentées automatiquement. Si votre module surcharge request/5, veillez à appeler super pour préserver l’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