Class: GraphQL::Tracing::DetailedTrace

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/tracing/detailed_trace.rb,
lib/graphql/tracing/detailed_trace/redis_backend.rb,
lib/graphql/tracing/detailed_trace/memory_backend.rb

Overview

DetailedTrace can make detailed profiles for a subset of production traffic.

When MySchema.detailed_trace?(query) returns true, a profiler-specific trace_mode: ... will be used for the query, overriding the one in context[:trace_mode].

Redis: The sampler stores its results in a provided Redis database. Depending on your needs, You can configure this database to retail all data (persistent) or to expire data according to your rules. If you need to save traces indefinitely, you can download them from Perfetto after opening them there.

Examples:

Adding the sampler to your schema

class MySchema < GraphQL::Schema
  # Add the sampler:
  use GraphQL::Tracing::DetailedTrace, redis: Redis.new(...), limit: 100

  # And implement this hook to tell it when to take a sample:
  def self.detailed_trace?(query)
    # Could use `query.context`, `query.selected_operation_name`, `query.query_string` here
    # Could call out to Flipper, etc
    rand <= 0.000_1 # one in ten thousand
  end
end

See Also:

Defined Under Namespace

Classes: MemoryBackend, RedisBackend, StoredTrace

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(storage:, trace_mode:) ⇒ DetailedTrace



45
46
47
48
# File 'lib/graphql/tracing/detailed_trace.rb', line 45

def initialize(storage:, trace_mode:)
  @storage = storage
  @trace_mode = trace_mode
end

Instance Attribute Details

#trace_modeSymbol (readonly)



51
52
53
# File 'lib/graphql/tracing/detailed_trace.rb', line 51

def trace_mode
  @trace_mode
end

Class Method Details

.use(schema, trace_mode: :profile_sample, memory: false, redis: nil, limit: nil) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/graphql/tracing/detailed_trace.rb', line 33

def self.use(schema, trace_mode: :profile_sample, memory: false, redis: nil, limit: nil)
  storage = if redis
    RedisBackend.new(redis: redis, limit: limit)
  elsif memory
    MemoryBackend.new(limit: limit)
  else
    raise ArgumentError, "Pass `redis: ...` to store traces in Redis for later review"
  end
  schema.detailed_trace = self.new(storage: storage, trace_mode: trace_mode)
  schema.trace_with(PerfettoTrace, mode: trace_mode, save_profile: true)
end

Instance Method Details

#delete_all_tracesvoid



76
77
78
# File 'lib/graphql/tracing/detailed_trace.rb', line 76

def delete_all_traces
  @storage.delete_all_traces
end

#delete_trace(id) ⇒ void



71
72
73
# File 'lib/graphql/tracing/detailed_trace.rb', line 71

def delete_trace(id)
  @storage.delete_trace(id)
end

#find_trace(id) ⇒ StoredTrace?



66
67
68
# File 'lib/graphql/tracing/detailed_trace.rb', line 66

def find_trace(id)
  @storage.find_trace(id)
end

#save_trace(operation_name, duration_ms, begin_ms, trace_data) ⇒ String



54
55
56
# File 'lib/graphql/tracing/detailed_trace.rb', line 54

def save_trace(operation_name, duration_ms, begin_ms, trace_data)
  @storage.save_trace(operation_name, duration_ms, begin_ms, trace_data)
end

#traces(last: nil, before: nil) ⇒ Enumerable<StoredTrace>



61
62
63
# File 'lib/graphql/tracing/detailed_trace.rb', line 61

def traces(last: nil, before: nil)
  @storage.traces(last: last, before: before)
end