Scout Elixir Instrumented Libraries¶
Our install instructions walk through instrumenting the following libraries:
- Phoenix
- controllers
- views
- templates
- Ecto 2.0
- Slime Templates
See instrumenting common librariess for guides on instrumenting other Elixir libraries.
Instrumenting Common Elixir Libraries¶
We’ve collected best practices for instrumenting common transactions and timing functions below. If you have a suggestion, please share it. See our custom instrumentation quickstart for more details on adding instrumentation.
- Transactions
- Timing
Phoenix Channels¶
Web or background transactions?¶
- web: For channel-related functions that impact the user-facing experience. Time spent in these transactions will appear on your app overboard dashboard and appear in the “Web” area of the UI.
- background: For functions that don’t have an impact on the user-facing experience (example: click-tracking). These will be available in the “Background Jobs” area of the UI.
Naming channel transactions¶
Provide an identifiable name based on the message the handle_out/ or handle_in/ function receives.
An example:
defmodule FirestormWeb.Web.PostsChannel do
use FirestormWeb.Web, :channel
use ScoutApm.Tracing
# Will appear under "Web" in the UI, named "PostsChannel.update"
@transaction(type: "web", name: "PostsChannel.update")
def handle_out("update", msg, socket) do
push socket, "update", FetchView.render("index.json", msg)
end
GenServer calls¶
It’s common to use GenServer to handle background work outside the web request flow. Suggestions:
- Treat these as
backgroundtransactions - Provide a
namebased on the message eachhandle_call/function handles.
An example:
defmodule Flight.Checker do
use GenServer
use ScoutApm.Tracing
# Will appear under "Background Jobs" in the UI, named "Flight.handle_check".
@transaction(type: "background", name: "check")
def handle_call({:check, flight}, _from, state) do
# Do work...
end
Task.start¶
These execute asynchronously, so treat as a background transaction.
Task.start(fn ->
# Will appear under "Background Jobs" in the UI, named "Crawler.crawl".
ScoutApm.Tracing.transaction(:background,"Crawler.crawl") do
Crawler.crawl(url)
end
end)
Task.Supervisor.start_child¶
Like Task.start, these execute asynchronously, so treat as a background transaction.
Task.Supervisor.start_child(YourApp.TaskSupervisor, fn ->
# Will appear under "Background Jobs" in the UI, named "Crawler.crawl".
ScoutApm.Tracing.transaction(:background,"Crawler.crawl") do
Crawler.crawl(url)
end
end)
Exq¶
To instrument Exq background jobs, use ScoutApm.Tracing, and add a @transaction module attribute to each worker’s perform function:
defmodule MyWorker do
use ScoutApm.Tracing
# Will appear under "Background Jobs" in the UI, named "MyWorker.perform".
@transaction(type: "background")
def perform(arg1, arg2) do
# do work
end
end
Absinthe¶
Requests to the Absinthe plug can be grouped by the GraphQL operationName under the “Web” UI by adding this plug to your pipeline.
HTTPoison¶
Download this Demo.HTTPClient module (you can rename to something more fitting) into your app’s /lib folder, then alias Demo.HTTPClient when calling HTTPoison functions:
defmodule Demo.Web.PageController do
use Demo.Web, :controller
# Will route function calls to `HTTPoision` through `Demo.HTTPClient`, which times the execution of the HTTP call.
alias Demo.HTTPClient
def index(conn, _params) do
# "HTTP" will appear on timeseries charts. "HTTP/get" and the url "https://cnn.com" will appear in traces.
case HTTPClient.get("https://cnn.com") do
{:ok, %HTTPoison.Response{} = response} ->
# do something with response
render(conn, "index.html")
{:error, %HTTPoison.Error{} = error} ->
# do something with error
render(conn, "error.html")
end
HTTPClient.post("https://cnn.com", "")
HTTPClient.get!("http://localhost:4567")
render(conn, "index.html")
end
end
MongoDB Ecto¶
Download this example MongoDB Repo module to use inplace of your existing MongoDB Repo module.
Custom Instrumentation
You can extend Scout to record additional types of transactions (background jobs, for example) and time the execution of code that fall outside our custom instrumentation.
For full details on instrumentation functions, see our ScoutApm.Tracing Hex docs.