Skip to content

Commit

Permalink
Add prometheus trace
Browse files Browse the repository at this point in the history
  • Loading branch information
rmosolgo committed Feb 16, 2023
1 parent e46a43b commit 75ca4c9
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/graphql/tracing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
require "graphql/tracing/new_relic_trace"
require "graphql/tracing/scout_trace"
require "graphql/tracing/statsd_trace"
# require "graphql/tracing/prometheus_trace"
require "graphql/tracing/prometheus_trace"
if defined?(PrometheusExporter::Server)
require "graphql/tracing/prometheus_tracing/graphql_collector"
end
Expand Down
89 changes: 89 additions & 0 deletions lib/graphql/tracing/prometheus_trace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

module GraphQL
module Tracing
module PrometheusTrace
include PlatformTrace

def initialize(client: PrometheusExporter::Client.default, keys_whitelist: ["execute_field", "execute_field_lazy"], collector_type: "graphql", **rest)
@client = client
@keys_whitelist = keys_whitelist
@collector_type = collector_type

super(**rest)
end

{
'lex' => "graphql.lex",
'parse' => "graphql.parse",
'validate' => "graphql.validate",
'analyze_query' => "graphql.analyze",
'analyze_multiplex' => "graphql.analyze",
'execute_multiplex' => "graphql.execute",
'execute_query' => "graphql.execute",
'execute_query_lazy' => "graphql.execute",
}.each do |trace_method, platform_key|
module_eval <<-RUBY, __FILE__, __LINE__
def #{trace_method}(**data, &block)
instrument_execution("#{platform_key}", "#{trace_method}", &block)
end
RUBY
end

def platform_execute_field(platform_key, _data, &block)
instrument_execution(platform_key, "execute_field", &block)
end

def platform_execute_field_lazy(platform_key, _data, &block)
instrument_execution(platform_key, "execute_field_lazy", &block)
end

def platform_authorized(platform_key, &block)
instrument_execution(platform_key, "authorized", &block)
end

def platform_authorized_lazy(platform_key, &block)
instrument_execution(platform_key, "authorized_lazy", &block)
end

def platform_resolve_type(platform_key, &block)
instrument_execution(platform_key, "resolve_type", &block)
end

def platform_resolve_type_lazy(platform_key, &block)
instrument_execution(platform_key, "resolve_type_lazy", &block)
end

def platform_field_key(type, field)
"#{type.graphql_name}.#{field.graphql_name}"
end

def platform_authorized_key(type)
"#{type.graphql_name}.authorized"
end

def platform_resolve_type_key(type)
"#{type.graphql_name}.resolve_type"
end

private

def instrument_execution(platform_key, key, &block)
if @keys_whitelist.include?(key)
start = ::Process.clock_gettime ::Process::CLOCK_MONOTONIC
result = block.call
duration = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start
@client.send_json(
type: @collector_type,
duration: duration,
platform_key: platform_key,
key: key
)
result
else
yield
end
end
end
end
end
38 changes: 38 additions & 0 deletions spec/graphql/tracing/prometheus_trace_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "spec_helper"

describe GraphQL::Tracing::PrometheusTracing do
module PrometheusTraceTest
class Query < GraphQL::Schema::Object
field :int, Integer, null: false

def int
1
end
end

class Schema < GraphQL::Schema
query Query

end
end

describe "Observing" do
it "sends JSON to Prometheus client" do
client = Minitest::Mock.new

client.expect :send_json, true do |obj|
obj[:type] == 'graphql' &&
obj[:key] == 'execute_field' &&
obj[:platform_key] == 'Query.int'
end

PrometheusTraceTest::Schema.trace_with GraphQL::Tracing::PrometheusTrace,
client: client,
trace_scalars: true

PrometheusTraceTest::Schema.execute "query X { int }"
end
end
end

0 comments on commit 75ca4c9

Please sign in to comment.