Skip to content

Instantly share code, notes, and snippets.

@tanguyantoine
Created August 19, 2017 18:01
Show Gist options
  • Save tanguyantoine/b06e6af1fc38d43677ca70eab5d53a26 to your computer and use it in GitHub Desktop.
Save tanguyantoine/b06e6af1fc38d43677ca70eab5d53a26 to your computer and use it in GitHub Desktop.
New Relic GraphQL Ruby instrumentation
Types::FoosType = GraphQL::ObjectType.define do
field :foos, !types[Types::FooType] do
timed true # enable New Relic trace_execution_scoped
description "Returns foos"
argument :per, types.Int, default_value: 20
argument :page, types.Int, default_value: 1
# Moving to cursor pagination would be better
resolve(...)
end
end
class NewRelicInstrumentation
extend ::NewRelic::Agent::MethodTracer
def before_query(query)
query.context[:query_start_time] = Time.current
end
# Add extra attributes to new Relic
def after_query(query)
duration = Time.current - query.context[:query_start_time]
::NewRelic::Agent.add_custom_attributes(
{
GQLDuration: duration * 1000.0,
GQLOperationName: query.operation_name
}
)
if query.context[:graphql_controller]
NewRelic::Agent.set_transaction_name("GraphQL/#{query.operation_name}")
end
end
def instrument(type, field)
if field.metadata[:timed]
old_resolve_proc = field.resolve_proc
new_resolve_proc = lambda do |obj, args, ctx|
self.class.trace_execution_scoped(["GraphQL/field/#{type.name}.#{field.name}"]) do
old_resolve_proc.call(obj, args, ctx)
end
end
field.redefine do
resolve(new_resolve_proc)
end
else
field
end
end
end
# allow fields to used timed true
GraphQL::Field.accepts_definitions timed: GraphQL::Define.assign_metadata_key(:timed)
GraphQLSchema = GraphQL::Schema.define do
query(QueryRootType)
mutation(MutationRootType)
instrument(:query, NewRelicInstrumentation.new)
instrument(:field, NewRelicInstrumentation.new)
end
# Log query depth
log_query_depth = GraphQL::Analysis::QueryDepth.new do |_query, depth|
::NewRelic::Agent.add_custom_attributes({ GQLDepth: depth })
Rails.logger.debug { "[GraphQL Query Depth] #{depth}" }
end
GraphQLSchema.query_analyzers << log_query_depth
# Log query Complexity
log_query_complexity = GraphQL::Analysis::QueryComplexity.new do |_query, complexity|
::NewRelic::Agent.add_custom_attributes({ GQLComplexity: complexity })
Rails.logger.debug { "[GraphQL Query Complexity] #{complexity}" }
end
GraphQLSchema.query_analyzers << log_query_complexity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment