graphql: data dog instrumentation
closes RECNVS-325 Test plan: * do something to monitor statsd traffic (maybe `nc -kul 8125`?) * queries written in graphiql should not be instrumented * student context card queries should be logged Change-Id: Ie86075b739df36e49b5f9ebcf320e50f8c140ecc Reviewed-on: https://gerrit.instructure.com/141965 Tested-by: Jenkins Reviewed-by: Jonathan Featherstone <jfeatherstone@instructure.com> QA-Review: Collin Parrish <cparrish@instructure.com> Product-Review: Cameron Matheson <cameron@instructure.com>
This commit is contained in:
parent
c2f729c303
commit
29e1b69f06
|
@ -163,3 +163,4 @@ gem 'twitter', path: 'gems/twitter'
|
|||
gem 'vericite_api', '1.5.3'
|
||||
gem 'utf8_cleaner', path: 'gems/utf8_cleaner'
|
||||
gem 'workflow', path: 'gems/workflow'
|
||||
gem 'dogstatsd-ruby', '3.3.0'
|
||||
|
|
|
@ -4,22 +4,32 @@ class GraphQLController < ApplicationController
|
|||
before_action :require_user, except: :execute
|
||||
before_action :require_graphql_feature_flag
|
||||
|
||||
|
||||
def execute
|
||||
query = params[:query]
|
||||
variables = params[:variables] || {}
|
||||
tracers = if request.headers["GraphQL-Metrics"] == "true"
|
||||
domain = request.host_with_port.sub(':', '_')
|
||||
[Tracers::DatadogTracer.new(domain)]
|
||||
else
|
||||
[]
|
||||
end
|
||||
context = {
|
||||
current_user: @current_user,
|
||||
session: session,
|
||||
request: request,
|
||||
tracers: tracers
|
||||
}
|
||||
result = nil
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
timeout = Integer(Setting.get('graphql_statement_timeout', '60_000'))
|
||||
ActiveRecord::Base.connection.execute "SET statement_timeout = #{timeout}"
|
||||
|
||||
result = CanvasSchema.execute(query, variables: variables, context: context)
|
||||
render json: result
|
||||
end
|
||||
|
||||
render json: result
|
||||
end
|
||||
|
||||
def graphiql
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
require 'datadog/statsd'
|
||||
|
||||
module Tracers
|
||||
class DatadogTracer
|
||||
def initialize(domain)
|
||||
@domain = domain
|
||||
@statsd = Datadog::Statsd.new('localhost', 8125)
|
||||
end
|
||||
|
||||
def trace(key, metadata)
|
||||
if key == "execute_query"
|
||||
@statsd.batch do |statsd|
|
||||
query_name = metadata[:query].operation_name || "unnamed"
|
||||
tags = [
|
||||
"query_md5:#{Digest::MD5.hexdigest(metadata[:query].query_string)}",
|
||||
"domain:#@domain",
|
||||
]
|
||||
statsd.increment("graphql.#{query_name}.count", tags: tags)
|
||||
statsd.time("graphql.#{query_name}.time", tags: tags) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
else
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,6 +10,7 @@ const client = new ApolloClient({
|
|||
opts: {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'GraphQL-Metrics': true,
|
||||
'X-CSRF-Token': $.cookie('_csrf_token') // TODO: probably need to move this io a middleware (http://dev.apollodata.com/core/network.html)
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
|
|
|
@ -62,5 +62,18 @@ describe GraphQLController do
|
|||
post :execute, params: {query: "{}"}
|
||||
expect(JSON.parse(response.body)["errors"]).not_to be_blank
|
||||
end
|
||||
|
||||
context "data dog metrics" do
|
||||
it "reports data dog metrics if requested" do
|
||||
expect_any_instance_of(Tracers::DatadogTracer).to receive :trace
|
||||
request.headers["GraphQL-Metrics"] = "true"
|
||||
post :execute, params: {query: '{legacyNode(User, 1) { id }'}
|
||||
end
|
||||
|
||||
it "doesn't report normally" do
|
||||
expect_any_instance_of(Tracers::DatadogTracer).not_to receive :trace
|
||||
post :execute, params: {query: '{legacyNode(User, 1) { id }'}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue