skylight-core 4.2.0 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a473587df8be0c1cf35b0296875e2cbd3c47d678be913e61c770e7d29d30756a
4
- data.tar.gz: d637956868b2c614225343bf10a063038778df91418053222d7a5e5038fcaa69
3
+ metadata.gz: 2443077b98bc42af5683f82aac17e192670026cbd6bdfa9a940caff2237860a0
4
+ data.tar.gz: e0dc413f3f0d0827f4b064b8fdfbac13f607357113ed50a223f9522e5775b5e0
5
5
  SHA512:
6
- metadata.gz: 91aebd0cfa951251a62903542df63949db425718233e178d362318bce81e4ccd865372e4d1cd9891d1adc09d87d8ac182daf5e5c6c7ded5b81f800ba1faa3374
7
- data.tar.gz: 4d442162789bcbd47ae5bc37fabdaf49650c0fb4f7fc8b50c6a4c2c63cfe6271cd66191db27114d9985ffdcaf5a82effad58984065411b469d9cafa064f3ed63
6
+ metadata.gz: e3ae4c018808967cf5b0cec1fb9056c037f37c2cd60b1790759755d1d9e05cba3f400a790502110fa5723541ad03f0fcf50eeb0d3ebc546d9ff19eb3c8d00309
7
+ data.tar.gz: ca5ca4747d2ec5a578f830dc5ee1ef818a651ca9a9f95ad069cfd26849014279f9aa4f9d3f2040eaf6de8ea64501959fbab005800c96107d17fe9f92b572517c
@@ -44,17 +44,31 @@ module Skylight::Core
44
44
  end
45
45
  end
46
46
 
47
- def self.with_after_close(resp, &block)
47
+ def self.with_after_close(resp, debug_identifier: "unknown", &block)
48
48
  # Responses should be arrays but in some situations they aren't
49
49
  # e.g. https://github.com/ruby-grape/grape/issues/1041
50
- # The safest approach seems to be to rely on implicit destructuring
51
- # since that is currently what Rack::Lint does.
52
50
  # See also https://github.com/rack/rack/issues/1239
53
- status, headers, body = resp
54
51
 
52
+ unless resp.respond_to?(:to_ary)
53
+ if resp.respond_to?(:to_a)
54
+ log_target.warn("Rack response from \"#{debug_identifier}\" cannot be implicitly converted to an array. This is in violation of "\
55
+ "the Rack SPEC and will raise an error in future versions.")
56
+ resp = resp.to_a
57
+ else
58
+ log_target.error("Rack response from \"#{debug_identifier}\" cannot be converted to an array. This is in violation of the Rack SPEC "\
59
+ "and may cause problems with Skylight operation.")
60
+ return resp
61
+ end
62
+ end
63
+
64
+ status, headers, body = resp
55
65
  [status, headers, BodyProxy.new(body, &block)]
56
66
  end
57
67
 
68
+ def self.log_target
69
+ @log_target ||= (Skylight::Core::Fanout.registered.first&.config || Logger.new(STDERR))
70
+ end
71
+
58
72
  include Util::Logging
59
73
 
60
74
  # For Util::Logging
@@ -84,7 +98,7 @@ module Skylight::Core
84
98
  resp = @app.call(env)
85
99
 
86
100
  if trace
87
- Middleware.with_after_close(resp) { trace.submit }
101
+ Middleware.with_after_close(resp, debug_identifier: "Rack App: #{@app.class}") { trace.submit }
88
102
  else
89
103
  resp
90
104
  end
@@ -4,12 +4,12 @@ module Skylight::Core
4
4
  class Perform < Normalizer
5
5
  register "perform.active_job"
6
6
 
7
- DELIVERY_JOB = "ActionMailer::DeliveryJob".freeze
7
+ DELIVERY_JOB = /\AActionMailer::(Mail)?DeliveryJob\Z/.freeze
8
8
  DELAYED_JOB_WRAPPER = "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper".freeze
9
9
 
10
10
  def self.normalize_title(job_instance)
11
11
  job_instance.class.name.to_s.tap do |str|
12
- if str == DELIVERY_JOB
12
+ if str.match(DELIVERY_JOB)
13
13
  mailer_class, mailer_method, * = job_instance.arguments
14
14
  return ["#{mailer_class}##{mailer_method}", str]
15
15
  end
@@ -25,7 +25,8 @@ module Skylight::Core
25
25
  end
26
26
 
27
27
  def get_namespace(endpoint)
28
- ::Grape::Namespace.joined_space(endpoint.namespace_stackable(:namespace))
28
+ # slice off preceding slash for data continuity
29
+ ::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1..-1]
29
30
  end
30
31
  end
31
32
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/inflector"
4
+
3
5
  module Skylight::Core::Normalizers::GraphQL
4
6
  # Some AS::N events in GraphQL are not super useful.
5
7
  # We are purposefully ignoring the following keys (and you probably shouldn't add them):
@@ -11,25 +13,61 @@ module Skylight::Core::Normalizers::GraphQL
11
13
  ANONYMOUS = "[anonymous]".freeze
12
14
  CAT = "app.graphql".freeze
13
15
 
14
- def normalize(_trace, name, _payload)
15
- [CAT, name, nil]
16
+ if defined?(::GraphQL::VERSION) && Gem::Version.new(::GraphQL::VERSION) >= Gem::Version.new("1.10")
17
+ def self.register_graphql
18
+ register("#{key}.graphql")
19
+ end
20
+ else
21
+ def self.register_graphql
22
+ register("graphql.#{key}")
23
+ end
24
+ end
25
+
26
+ def self.inherited(klass)
27
+ klass.const_set(
28
+ :KEY,
29
+ ActiveSupport::Inflector.underscore(
30
+ ActiveSupport::Inflector.demodulize(klass.name)
31
+ ).freeze
32
+ )
33
+ end
34
+
35
+ def self.key
36
+ self::KEY
16
37
  end
38
+
39
+ def normalize(_trace, _name, _payload)
40
+ [CAT, "graphql.#{key}", nil]
41
+ end
42
+
43
+ private
44
+
45
+ def key
46
+ self.class.key
47
+ end
48
+
49
+ def extract_query_name(query)
50
+ query&.context&.[](:skylight_endpoint) ||
51
+ query&.operation_name ||
52
+ ANONYMOUS
53
+ end
17
54
  end
18
55
 
19
56
  class Lex < Base
20
- register "graphql.lex"
57
+ register_graphql
21
58
  end
22
59
 
23
60
  class Parse < Base
24
- register "graphql.parse"
61
+ register_graphql
25
62
  end
26
63
 
27
64
  class Validate < Base
28
- register "graphql.validate"
65
+ register_graphql
29
66
  end
30
67
 
31
68
  class ExecuteMultiplex < Base
32
- register "graphql.execute_multiplex"
69
+ register_graphql
70
+
33
71
  def normalize_after(trace, _span, _name, payload)
34
72
  # This is in normalize_after because the queries may not have
35
73
  # an assigned operation name before they are executed.
@@ -44,7 +82,7 @@ module Skylight::Core::Normalizers::GraphQL
44
82
  # has not been done yet at the point where execute_multiplex starts.
45
83
  # [1] https://graphql.org/learn/serving-over-http/#post-request
46
84
  queries, has_errors = payload[:multiplex].queries.each_with_object([Set.new, Set.new]) do |query, (names, errors)|
47
- names << (query.operation_name || ANONYMOUS)
85
+ names << extract_query_name(query)
48
86
  errors << query.static_errors.any?
49
87
  end
50
88
 
@@ -58,14 +96,14 @@ module Skylight::Core::Normalizers::GraphQL
58
96
  end
59
97
 
60
98
  class AnalyzeQuery < Base
61
- register "graphql.analyze_query"
99
+ register_graphql
62
100
  end
63
101
 
64
102
  class ExecuteQuery < Base
65
- register "graphql.execute_query"
103
+ register_graphql
66
104
 
67
- def normalize(trace, name, payload)
68
- query_name = payload[:query]&.operation_name || ANONYMOUS
105
+ def normalize(trace, _name, payload)
106
+ query_name = extract_query_name(payload[:query])
69
107
 
70
108
  if query_name == ANONYMOUS
71
109
  meta = { mute_children: true }
@@ -75,18 +113,18 @@ module Skylight::Core::Normalizers::GraphQL
75
113
  # but in the case of a single query, it will be the same value anyway.
76
114
  trace.endpoint = "graphql:#{query_name}"
77
115
 
78
- [CAT, "#{name}: #{query_name}", nil, meta]
116
+ [CAT, "graphql.#{key}: #{query_name}", nil, meta]
79
117
  end
80
118
  end
81
119
 
82
120
  class ExecuteQueryLazy < ExecuteQuery
83
- register "graphql.execute_query_lazy"
121
+ register_graphql
84
122
 
85
- def normalize(trace, name, payload)
123
+ def normalize(trace, _name, payload)
86
124
  if payload[:query]
87
125
  super
88
126
  elsif payload[:multiplex]
89
- [CAT, "#{name}.multiplex", nil]
127
+ [CAT, "graphql.#{key}.multiplex", nil]
90
128
  end
91
129
  end
92
130
  end
@@ -27,6 +27,13 @@ module Skylight::Core
27
27
  elsif respond_to?(:rendered_format) && rendered_format
28
28
  rendered_format
29
29
  end
30
+ rescue
31
+ # There are cases in which actionpack can return
32
+ # a stringified representation of a Mime::NullType instance,
33
+ # which is invalid for a number of reasons. This string raises
34
+ # errors when piped through Mime::Type.lookup, so it's probably
35
+ # best to just return nil in those cases.
36
+ nil
30
37
  end
31
38
  end
32
39
  end
@@ -3,35 +3,36 @@
3
3
  module Skylight::Core
4
4
  module Probes
5
5
  module GraphQL
6
+ module Instrumentation
7
+ def initialize(*, **)
8
+ super
9
+
10
+ return unless defined?(@tracers)
11
+
12
+ unless @tracers.include?(::GraphQL::Tracing::ActiveSupportNotificationsTracing)
13
+ @tracers << ::GraphQL::Tracing::ActiveSupportNotificationsTracing
14
+ end
15
+ end
16
+ end
17
+
6
18
  class Probe
7
19
  def install
8
- ::GraphQL::Schema.class_eval do
9
- alias_method :multiplex_without_sk, :multiplex
10
-
11
- # Schema#execute also delegates to multiplex, so this is the only method
12
- # we need to override.
13
- def multiplex(*args, &block)
14
- sk_add_tracer
15
- multiplex_without_sk(*args, &block)
16
- end
17
-
18
- def sk_add_tracer
19
- Skylight::Core::Config::MUTEX.synchronize do
20
- graphql_tracer = ::GraphQL::Tracing::ActiveSupportNotificationsTracing
21
- unless tracers.include?(graphql_tracer)
22
- $stdout.puts "[SKYLIGHT::CORE] Adding tracer 'GraphQL::Tracing::ActiveSupportNotificationsTracing' to schema"
23
- tracers << graphql_tracer
24
- end
25
-
26
- class << self
27
- # Remove the probe and reset multiplex/execute to original version
28
- # after the tracer has been added
29
- alias_method :multiplex, :multiplex_without_sk
30
- end
31
- end
32
- end
20
+ tracing_klass_name = "::GraphQL::Tracing::ActiveSupportNotificationsTracing"
21
+ klasses_to_probe = %w(
22
+ ::GraphQL::Execution::Multiplex
23
+ ::GraphQL::Query
24
+ )
25
+
26
+ return unless ([tracing_klass_name] + klasses_to_probe).all?(&method(:safe_constantize))
27
+
28
+ klasses_to_probe.each do |klass_name|
29
+ safe_constantize(klass_name).prepend(Instrumentation)
33
30
  end
34
31
  end
32
+
33
+ def safe_constantize(klass_name)
34
+ Skylight::Core::Util::Inflector.safe_constantize(klass_name)
35
+ end
35
36
  end
36
37
  end
37
38
 
@@ -33,7 +33,7 @@ module Skylight::Core
33
33
  spans = Skylight::Core::Fanout.instrument(title: name, category: "#{category}")
34
34
  resp = call_without_sk(*args, &block)
35
35
 
36
- proxied_response = Skylight::Core::Middleware.with_after_close(resp) do
36
+ proxied_response = Skylight::Core::Middleware.with_after_close(resp, debug_identifier: "Middleware: #{name}") do
37
37
  Skylight::Core::Fanout.done(spans)
38
38
  end
39
39
  rescue Exception => err
@@ -1,5 +1,5 @@
1
1
  module Skylight
2
2
  module Core
3
- VERSION = "4.2.0".freeze
3
+ VERSION = "4.3.1".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-30 00:00:00.000000000 Z
11
+ date: 2020-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -269,8 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
269
  - !ruby/object:Gem::Version
270
270
  version: '0'
271
271
  requirements: []
272
- rubyforge_project:
273
- rubygems_version: 2.7.6
272
+ rubygems_version: 3.1.2
274
273
  signing_key:
275
274
  specification_version: 4
276
275
  summary: The core methods of the Skylight profiler.