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.

Copy link

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.

Copy link

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
  ....

@MartinElvar

This comment has been minimized.

Copy link

MartinElvar commented Dec 17, 2018

What would a plug free solution look like? Is there a way to do this using a Absinthe plugin?
We are using websockets for communication, hence the plug pipeline is not hit.

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