Skip to content

Instantly share code, notes, and snippets.

@itsderek23
Last active March 4, 2020 06:58
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itsderek23/d9435b21c9a44cd9629e93c4e8c2750e to your computer and use it in GitHub Desktop.
Save itsderek23/d9435b21c9a44cd9629e93c4e8c2750e to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link

@cpursley
Copy link

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
Copy link

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