Module: GraphQL::Tracing::MonitorTrace
- Defined in:
- lib/graphql/tracing/monitor_trace.rb
Overview
This module is the basis for Ruby-level integration with third-party monitoring platforms. Platform-specific traces include this module and implement an adapter.
Defined Under Namespace
Classes: Monitor
Constant Summary collapse
- MODULE_TEMPLATE =
<<~RUBY # @param set_transaction_name [Boolean] If `true`, use the GraphQL operation name as the request name on the monitoring platform # @param trace_scalars [Boolean] If `true`, leaf fields will be traced too (Scalars _and_ Enums) # @param trace_authorized [Boolean] If `false`, skip tracing `authorized?` calls # @param trace_resolve_type [Boolean] If `false`, skip tracing `resolve_type?` calls def initialize(...) setup_%{monitor}_monitor(...) super end def setup_%{monitor}_monitor(trace_scalars: false, trace_authorized: true, trace_resolve_type: true, set_transaction_name: false, **kwargs) @trace_scalars = trace_scalars @trace_authorized = trace_authorized @trace_resolve_type = trace_resolve_type @set_transaction_name = set_transaction_name @%{monitor} = %{monitor_class}.new(trace: self, set_transaction_name: @set_transaction_name, **kwargs) end def parse(query_string:) @%{monitor}.instrument(:parse, query_string) do super end end def lex(query_string:) @%{monitor}.instrument(:lex, query_string) do super end end def validate(query:, validate:) @%{monitor}.instrument(:validate, query) do super end end def begin_analyze_multiplex(multiplex, analyzers) begin_%{monitor}_event(:analyze, nil) super end def end_analyze_multiplex(multiplex, analyzers) finish_%{monitor}_event super end def execute_multiplex(multiplex:) @%{monitor}.instrument(:execute, multiplex) do super end end def begin_execute_field(field, object, arguments, query) return_type = field.type.unwrap trace_field = if return_type.kind.scalar? || return_type.kind.enum? (field.trace.nil? && @trace_scalars) || field.trace else true end if trace_field begin_%{monitor}_event(:execute_field, field) end super end def end_execute_field(field, object, arguments, query, result) finish_%{monitor}_event super end def dataloader_fiber_yield(source) Fiber[PREVIOUS_EV_KEY] = finish_%{monitor}_event super end def dataloader_fiber_resume(source) prev_ev = Fiber[PREVIOUS_EV_KEY] if prev_ev begin_%{monitor}_event(prev_ev.keyword, prev_ev.object) end super end def begin_authorized(type, object, context) @trace_authorized && begin_%{monitor}_event(:authorized, type) super end def end_authorized(type, object, context, result) finish_%{monitor}_event super end def begin_resolve_type(type, value, context) @trace_resolve_type && begin_%{monitor}_event(:resolve_type, type) super end def end_resolve_type(type, value, context, resolved_type) finish_%{monitor}_event super end def begin_dataloader_source(source) begin_%{monitor}_event(:dataloader_source, source) super end def end_dataloader_source(source) finish_%{monitor}_event super end CURRENT_EV_KEY = :__graphql_%{monitor}_trace_event PREVIOUS_EV_KEY = :__graphql_%{monitor}_trace_previous_event private def begin_%{monitor}_event(keyword, object) Fiber[CURRENT_EV_KEY] = @%{monitor}.start_event(keyword, object) end def finish_%{monitor}_event if ev = Fiber[CURRENT_EV_KEY] ev.finish # Use `false` to prevent grabbing an event from a parent fiber Fiber[CURRENT_EV_KEY] = false ev end end RUBY
Class Method Summary collapse
Class Method Details
.create_module(monitor_name) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/graphql/tracing/monitor_trace.rb', line 137 def self.create_module(monitor_name) if !monitor_name.match?(/[a-z]+/) raise ArgumentError, "monitor name must be [a-z]+, not: #{monitor_name.inspect}" end trace_module = Module.new code = MODULE_TEMPLATE % { monitor: monitor_name, monitor_class: monitor_name.capitalize + "Monitor", } trace_module.module_eval(code, __FILE__, __LINE__ + 5) # rubocop:disable Development/NoEvalCop This is build-time with a validated string trace_module end |