New Feature: Traces spanning multiple processes

Starting with version 1.1.0, PryIn now supports traces spanning multiple processes.

This allows you to run code asynchronously and still have it appear as part of a parent trace.

To present an example: In the import_starships action our Star Wars (Phoenix) application fetches starships from an API and inserts them into the local database. This is done asynchronously in separate tasks:

def import_starships(conn, %{"starship_ids" => starship_ids}) do
  parent_pid = self()
  starships = for starship_id <- String.split(starship_ids, ",") do
    Task.async(fn ->
      PryIn.join_trace(parent_pid, self())
      data = StarWars.Endpoint.instrument :pryin, %{key: "get_starship"}, fn ->
        HTTPoison.get!("http://swapi.co/api/starships/#{starship_id}/").body
        |> Poison.decode!
      end

      %Starship{}
      |> Starship.changeset(data)
      |> Repo.insert!()
    end)
  end
  |> Enum.map(&Task.await/1)

  render(conn, "import_starships.html", %{starships: starships})
end

As everything inside the function passed to Task.async happens in a different process and traces in PryIn are tied to PIDs, normally neither the metrics about HTTPoison.get, nor about Repo.insert! would appear in the traces for the import_starhips action.

With PryIn.join_trace we tell PryIn that everything inside those child processes should be treated as if it was happening inside the parent process. Both the HTTPoison.get and the Repo.insert! data will now be part of the trace.

In PryIn this appear like so:

multi process traces inside PryIn

Notice the differently colored bars on the left of each row. Each color represents one process.

P.S.: You can find the Star Wars example application at https://github.com/pryin-io/star_wars.