Instantly share code, notes, and snippets.

Embed
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))
conn
|> Plug.Conn.register_before_send(&before_send/1)
end
def before_send(conn) do
full_name = action_name(conn)
uri = "#{conn.request_path}"
ScoutApm.TrackedRequest.stop_layer(fn layer ->
layer
|> Layer.update_name(full_name)
|> Layer.update_uri(uri)
end
)
conn
end
# 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"]
"GraphQL##{action_name}"
end
end
@percygrunwald

This comment has been minimized.

percygrunwald commented Jan 25, 2018

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) {
    id
  }
}

Here's what I arrived at: https://gist.github.com/pgrunwald/6dd1d9132855b0372785e75df4a26669

@cpursley

This comment has been minimized.

@cpursley

This comment has been minimized.

cpursley commented Dec 11, 2018

Also, add this Plug to the Router pipeline as follows:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
    plug MyAppWeb.Context
    # add here
    plug ScoutApm.Absinthe.Plug
  end
  ....

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