# frozen_string_literal: true
# Legacy tracing:
require "graphql/tracing/active_support_notifications_tracing"
require "graphql/tracing/platform_tracing"
require "graphql/tracing/appoptics_tracing"
require "graphql/tracing/appsignal_tracing"
require "graphql/tracing/data_dog_tracing"
require "graphql/tracing/new_relic_tracing"
require "graphql/tracing/scout_tracing"
require "graphql/tracing/statsd_tracing"
require "graphql/tracing/prometheus_tracing"
# New Tracing:
require "graphql/tracing/platform_trace"
require "graphql/tracing/appoptics_trace"
require "graphql/tracing/appsignal_trace"
require "graphql/tracing/data_dog_trace"
require "graphql/tracing/new_relic_trace"
require "graphql/tracing/notifications_trace"
require "graphql/tracing/scout_trace"
require "graphql/tracing/statsd_trace"
require "graphql/tracing/prometheus_trace"
if defined?(PrometheusExporter::Server)
require "graphql/tracing/prometheus_tracing/graphql_collector"
end
module GraphQL
module Tracing
class Trace
# @param multiplex [GraphQL::Execution::Multiplex, nil]
# @param query [GraphQL::Query, nil]
def initialize(multiplex: nil, query: nil, **_options)
@multiplex = multiplex
@query = query
end
def lex(query_string:)
yield
end
def parse(query_string:)
yield
end
def validate(query:, validate:)
yield
end
def analyze_multiplex(multiplex:)
yield
end
def analyze_query(query:)
yield
end
def execute_multiplex(multiplex:)
yield
end
def execute_query(query:)
yield
end
def execute_query_lazy(query:, multiplex:)
yield
end
def execute_field(field:, query:, ast_node:, arguments:, object:)
yield
end
def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
yield
end
def authorized(query:, type:, object:)
yield
end
def authorized_lazy(query:, type:, object:)
yield
end
def resolve_type(query:, type:, object:)
yield
end
def resolve_type_lazy(query:, type:, object:)
yield
end
end
NullTrace = Trace.new
class LegacyTrace < Trace
def lex(query_string:, &block)
(@multiplex || @query).trace("lex", { query_string: query_string }, &block)
end
def parse(query_string:, &block)
(@multiplex || @query).trace("parse", { query_string: query_string }, &block)
end
def validate(query:, validate:, &block)
query.trace("validate", { validate: validate, query: query }, &block)
end
def analyze_multiplex(multiplex:, &block)
multiplex.trace("analyze_multiplex", { multiplex: multiplex }, &block)
end
def analyze_query(query:, &block)
query.trace("analyze_query", { query: query }, &block)
end
def execute_multiplex(multiplex:, &block)
multiplex.trace("execute_multiplex", { multiplex: multiplex }, &block)
end
def execute_query(query:, &block)
query.trace("execute_query", { query: query }, &block)
end
def execute_query_lazy(query:, multiplex:, &block)
multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }, &block)
end
def execute_field(field:, query:, ast_node:, arguments:, object:, &block)
query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
end
def execute_field_lazy(field:, query:, ast_node:, arguments:, object:, &block)
query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
end
def authorized(query:, type:, object:, &block)
query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end
def authorized_lazy(query:, type:, object:, &block)
query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end
def resolve_type(query:, type:, object:, &block)
query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end
def resolve_type_lazy(query:, type:, object:, &block)
query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end
end
# Objects may include traceable to gain a `.trace(...)` method.
# The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
# @api private
module Traceable
# @param key [String] The name of the event in GraphQL internals
# @param metadata [Hash] Event-related metadata (can be anything)
# @return [Object] Must return the value of the block
def trace(key, metadata, &block)
return yield if @tracers.empty?
call_tracers(0, key, metadata, &block)
end
private
# If there's a tracer at `idx`, call it and then increment `idx`.
# Otherwise, yield.
#
# @param idx [Integer] Which tracer to call
# @param key [String] The current event name
# @param metadata [Object] The current event object
# @return Whatever the block returns
def call_tracers(idx, key, metadata, &block)
if idx == @tracers.length
yield
else
@tracers[idx].trace(key, metadata) { call_tracers(idx + 1, key, metadata, &block) }
end
end
end
module NullTracer
module_function
def trace(k, v)
yield
end
end
end
end