Class: CacheQL::FieldInstrumentation

Inherits:
Object
  • Object
show all
Defined in:
lib/cacheql/field_instrumentation.rb

Constant Summary collapse

NAME =
"graphql.field".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instrumenter) ⇒ FieldInstrumentation

instrumenter must respond to #instrument See ScoutApm::Tracer for example



32
33
34
# File 'lib/cacheql/field_instrumentation.rb', line 32

def initialize(instrumenter)
  @instrumenter = instrumenter
end

Class Method Details

.log(&block) ⇒ Object

For use in an around_action call to log all fields. For example:

around_action :log_field_instrumentation

def log_field_instrumentation(&block)

CacheQL::FieldInstrumentation.log(&block)

end



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/cacheql/field_instrumentation.rb', line 15

def self.log(&block)
  field_instruments = Hash.new(0)
  ActiveSupport::Notifications.subscribe(NAME) do |*args|
    event = ActiveSupport::Notifications::Event.new(*args)
    field_instruments[event.payload[:label]] += event.duration
  end

  block.call

  ActiveSupport::Notifications.unsubscribe(NAME)
  field_instruments.sort_by(&:last).reverse.each do |field, ms|
    CacheQL::Railtie.config.logger.info "[CacheQL::Tracing] #{field} took #{ms.round(3)}ms"
  end
end

Instance Method Details

#instrument(type, field) ⇒ Object

Track timing for all fields



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cacheql/field_instrumentation.rb', line 37

def instrument(type, field)
  # Ignore internal GraphQL types
  if type.name.starts_with?("__")
    field
  else
    label = "#{type.name}.#{field.name}"
    old_resolve_proc = field.resolve_proc

    new_resolve_proc = -> (obj, args, ctx) {
      ActiveSupport::Notifications.instrument(NAME, label: label) do
        @instrumenter.instrument("GraphQL", label) do
          resolved = old_resolve_proc.call(obj, args, ctx)
          resolved
        end
      end
    }

    # Return a copy of `field`, with a new resolve proc
    field.redefine do
      resolve(new_resolve_proc)
    end
  end
end