class GraphQL::Tracing::AppOpticsTracing
This class uses the AppopticsAPM SDK from the appoptics_apm gem to create traces for GraphQL
.
There are 4 configurations available. They can be set in the appoptics_apm config file or in code. Please see: {docs.appoptics.com/kb/apm_tracing/ruby/configure}
AppOpticsAPM::Config[:graphql][:enabled] = true|false AppOpticsAPM::Config[:graphql][:transaction_name] = true|false AppOpticsAPM::Config[:graphql][:sanitize_query] = true|false AppOpticsAPM::Config[:graphql][:remove_comments] = true|false
Constants
Public Class Methods
version()
click to toggle source
During auto-instrumentation this version of AppOpticsTracing
is compared with the version provided in the appoptics_apm gem, so that the newer version of the class can be used
# File lib/graphql/tracing/appoptics_tracing.rb, line 27 def self.version Gem::Version.new('1.0.0') end
Public Instance Methods
platform_field_key(type, field)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 57 def platform_field_key(type, field) "graphql.#{type.graphql_name}.#{field.graphql_name}" end
platform_resolve_type_key(type)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 65 def platform_resolve_type_key(type) "graphql.resolve_type.#{type.graphql_name}" end
platform_trace(platform_key, _key, data) { || ... }
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 42 def platform_trace(platform_key, _key, data) return yield if !defined?(AppOpticsAPM) || gql_config[:enabled] == false layer = span_name(platform_key) kvs = metadata(data, layer) kvs[:Key] = platform_key if (PREP_KEYS + EXEC_KEYS).include?(platform_key) transaction_name(kvs[:InboundQuery]) if kvs[:InboundQuery] && layer == 'graphql.execute' ::AppOpticsAPM::SDK.trace(layer, kvs) do kvs.clear # we don't have to send them twice yield end end
Private Instance Methods
gql_config()
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 71 def gql_config ::AppOpticsAPM::Config[:graphql] ||= {} end
graphql_context(context, layer)
click to toggle source
rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# File lib/graphql/tracing/appoptics_tracing.rb, line 124 def graphql_context(context, layer) context.errors && context.errors.each do |err| AppOpticsAPM::API.log_exception(layer, err) end [[:Path, context.path.join('.')]] end
graphql_multiplex(data)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 150 def graphql_multiplex(data) names = data.queries.map(&:operations).map(&:keys).flatten.compact multiplex_transaction_name(names) if names.size > 1 [:Operations, names.join(', ')] end
graphql_query(query)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 132 def graphql_query(query) return [] unless query query_string = query.query_string query_string = remove_comments(query_string) if gql_config[:remove_comments] != false query_string = sanitize(query_string) if gql_config[:sanitize_query] != false [[:InboundQuery, query_string], [:Operation, query.selected_operation_name]] end
graphql_query_string(query_string)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 143 def graphql_query_string(query_string) query_string = remove_comments(query_string) if gql_config[:remove_comments] != false query_string = sanitize(query_string) if gql_config[:sanitize_query] != false [:InboundQuery, query_string] end
metadata(data, layer)
click to toggle source
rubocop:disable Metrics/AbcSize, Metrics/MethodLength
# File lib/graphql/tracing/appoptics_tracing.rb, line 104 def metadata(data, layer) data.keys.map do |key| case key when :context graphql_context(data[key], layer) when :query graphql_query(data[key]) when :query_string graphql_query_string(data[key]) when :multiplex graphql_multiplex(data[key]) when :path [key, data[key].join(".")] else [key, data[key]] end end.flatten(2).each_slice(2).to_h.merge(Spec: 'graphql') end
multiplex_transaction_name(names)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 86 def multiplex_transaction_name(names) return if gql_config[:transaction_name] == false || ::AppOpticsAPM::SDK.get_transaction_name name = "graphql.multiplex.#{names.join('.')}" name = "#{name[0..251]}..." if name.length > 254 ::AppOpticsAPM::SDK.set_transaction_name(name) end
remove_comments(query)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 166 def remove_comments(query) return unless query query.gsub(/#[^\n\r]*/, '') end
sanitize(query)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 157 def sanitize(query) return unless query # remove arguments query.gsub(/"[^"]*"/, '"?"') # strings .gsub(/-?[0-9]*\.?[0-9]+e?[0-9]*/, '?') # ints + floats .gsub(/\[[^\]]*\]/, '[?]') # arrays end
span_name(key)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 96 def span_name(key) return 'graphql.prep' if PREP_KEYS.include?(key) return 'graphql.execute' if EXEC_KEYS.include?(key) key[/^graphql\./] ? key : "graphql.#{key}" end
transaction_name(query)
click to toggle source
# File lib/graphql/tracing/appoptics_tracing.rb, line 75 def transaction_name(query) return if gql_config[:transaction_name] == false || ::AppOpticsAPM::SDK.get_transaction_name split_query = query.strip.split(/\W+/, 3) split_query[0] = 'query' if split_query[0].empty? name = "graphql.#{split_query[0..1].join('.')}" ::AppOpticsAPM::SDK.set_transaction_name(name) end