Class: ApolloTracing

Inherits:
Object
  • Object
show all
Defined in:
lib/apollo_tracing.rb,
lib/apollo_tracing/version.rb

Constant Summary collapse

VERSION =
"1.6.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.start_proxy(config_filepath_or_json = 'config/apollo-engine.json') ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/apollo_tracing.rb', line 7

def self.start_proxy(config_filepath_or_json = 'config/apollo-engine.json')
  config_json =
    if File.exist?(config_filepath_or_json)
      File.read(config_filepath_or_json)
    else
      config_filepath_or_json
    end
  binary_path =
    if RUBY_PLATFORM.include?('darwin')
      File.expand_path('../../bin/engineproxy_darwin_amd64', __FILE__)
    elsif /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
      File.expand_path('../../bin/engineproxy_windows_amd64.exe', __FILE__)
    else
      File.expand_path('../../bin/engineproxy_linux_amd64', __FILE__)
    end

  @@proxy_pid = spawn(
    {"ENGINE_CONFIG" => config_json},
    "#{binary_path} -config=env",
    {out: STDOUT, err: STDERR}
  )
  at_exit { stop_proxy }
  Process.detach(@@proxy_pid)
  @@proxy_pid
end

.stop_proxyObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/apollo_tracing.rb', line 33

def self.stop_proxy
  Process.getpgid(@@proxy_pid)
  Process.kill('TERM', @@proxy_pid)

  3.times do
    Process.getpgid(@@proxy_pid)
    sleep 1
  end

  Process.getpgid(@@proxy_pid)
  puts "Couldn't cleanly terminate the Apollo Engine Proxy in 3 seconds!"
  Process.kill('KILL', @@proxy_pid)
rescue Errno::ESRCH
  # process does not exist
end

Instance Method Details

#after_query(query) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/apollo_tracing.rb', line 61

def after_query(query)
  result = query.result
  return if result.nil? || result.to_h.nil?
  end_time = Time.now.utc
  duration_nanos = duration_nanos(start_time: query.context['apollo-tracing']['start_time'], end_time: end_time)

  result["extensions"] ||= {}
  result["extensions"]["tracing"] = {
    "version" => 1,
    "startTime" => query.context['apollo-tracing']['start_time'].strftime('%FT%T.%3NZ'),
    "endTime" => end_time.strftime('%FT%T.%3NZ'),
    "duration" => duration_nanos,
    "execution" => {
      "resolvers" => query.context['apollo-tracing']['resolvers']
    }
  }
end

#before_query(query) ⇒ Object



54
55
56
57
58
59
# File 'lib/apollo_tracing.rb', line 54

def before_query(query)
  query.context['apollo-tracing'] = {
    'start_time' => Time.now.utc,
    'resolvers' => []
  }
end

#instrument(type, field) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/apollo_tracing.rb', line 79

def instrument(type, field)
  old_resolve_proc = field.resolve_proc

  new_resolve_proc = ->(obj, args, ctx) do
    resolve_start_time = Time.now.utc
    result = old_resolve_proc.call(obj, args, ctx)
    resolve_end_time = Time.now.utc

    ctx['apollo-tracing']['resolvers'] << {
      'path' => ctx.path,
      'parentType' => type.name,
      'fieldName' => field.name,
      'returnType' => field.type.to_s,
      'startOffset' => duration_nanos(start_time: ctx['apollo-tracing']['start_time'], end_time: resolve_start_time),
      'duration' => duration_nanos(start_time: resolve_start_time, end_time: resolve_end_time)
    }

    result
  end

  field.redefine { resolve(new_resolve_proc) }
end

#use(schema_definition) ⇒ Object



49
50
51
52
# File 'lib/apollo_tracing.rb', line 49

def use(schema_definition)
  schema_definition.instrument(:query, self)
  schema_definition.instrument(:field, self)
end