1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
# 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
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
{
'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
# rubocop:enable Development/NoEvalCop
def platform_execute_field(platform_key, &block)
instrument_execution(platform_key, "execute_field", &block)
end
def platform_execute_field_lazy(platform_key, &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(field)
field.path
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
|