Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Scout Absinthe (GraphQL) Instrumentation
defmodule ScoutApm.Absinthe.Plug do
alias ScoutApm.Internal.Layer
def init(default), do: default
def call(conn, _default) do
ScoutApm.TrackedRequest.start_layer("Controller", action_name(conn))
|> Plug.Conn.register_before_send(&before_send/1)
def before_send(conn) do
full_name = action_name(conn)
uri = "#{conn.request_path}"
ScoutApm.TrackedRequest.stop_layer(fn layer ->
|> Layer.update_name(full_name)
|> Layer.update_uri(uri)
# Takes a connection, extracts the phoenix controller & action, then manipulates & cleans it up.
# Returns a string like "PageController#index"
defp action_name(conn) do
action_name = conn.params["operationName"]

In case anyone is interested, the plug shown is dependent on the operationName being set for the GraphQL queries. For the project I'm working on, we don't name the queries/mutations we send to Absinthe, but limit each query/mutation to a single field per request. In this case, using the code above results in all GraphQL requests being labelled "GraphQL" in Scout. I needed a way to extract the first field so that queries/mutations like the one below show up as "GraphQL#firstField" in Scout.

query {
  firstField(id: 1) {

Here's what I arrived at:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment