skylight 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 466b969f1013fe2e80edfed072c777a9196bc5e72df4586fd129e71d13f68ef6
4
- data.tar.gz: e779017f866e565f5ce333b0c4118f4e6428eed72fc5a931e44dbc82d30f4080
3
+ metadata.gz: c1219b6ae71c3331396631a73e0866eb68d681eace43059b1c8690daca5e3634
4
+ data.tar.gz: 1b95ca11947bd572ebf69d5677cb9450533da0f86745a5733af64c4b3bed6fad
5
5
  SHA512:
6
- metadata.gz: 5f18a8b623a511912750df11dfeb91510510c977a4cc141a329f792ea4065d9ae11155ec68bd9f98cdf6aec7dd93a2e0b707a1955eee3e74a6c51fd6b0c7911f
7
- data.tar.gz: 36200567127b6ae47ef97f4c0b1dca385023128f28f63ee5c379c9e34b624fe15ea7565a7d0d5d8816c51427c642006a1e837c46498cc8fd22a5b25e02b10665
6
+ metadata.gz: 55c2b9c85310d9cb40afa744364759c854ac5b94787a285947986d85477b3df4119ff14da33b44e53fc2383499d61b70d0373aecbcebd9cbfbbe5d0fb11a022f
7
+ data.tar.gz: ff24d96979a028ba73c8c7d9942ae312d63a6a2eefe49354648fe39832e7f189babd2a85a1f4e06b7de6857c3188efae97f4b1f5e7fff9c30efecafc7b60a94a
@@ -1,3 +1,12 @@
1
+ ## 1.6.0 (March 21, 2018)
2
+
3
+ * [FEATURE] Time spent the Rails router is now identified separately in the trace
4
+ * [IMPROVEMENT] Switch logger to debug mode if tracing is enabled
5
+ * [IMPROVEMENT] Improved logging for a number of error cases
6
+ * [IMPROVEMENT] Middleware probe should now accept anything allowed by Rack::Lint
7
+ * [IMPROVEMENT] We were using arity checks to determine Rails version but due to other libraries' monkey patches this could sometimes fail. We just check version numbers now.
8
+ * [BUGFIX] Middleware probe no longer errors when Middleware returns a frozen array
9
+
1
10
  ## 1.5.1 (February 7, 2018)
2
11
 
3
12
  * [BUGFIX] `skylight doctor` no longer erroneously reports inability to reach Skylight servers.
@@ -220,7 +220,7 @@ $CFLAGS << " -std=c99 -Wall -fno-strict-aliasing"
220
220
 
221
221
  # Allow stricter checks to be turned on for development or debugging
222
222
  if SKYLIGHT_EXT_STRICT
223
- $CFLAGS << " -pedantic"
223
+ $CFLAGS << " -Wextra"
224
224
  end
225
225
 
226
226
  # TODO: Compute the relative path to the location
@@ -632,13 +632,18 @@ authentication: #{self[:authentication]}
632
632
  out = STDOUT if out == '-'
633
633
 
634
634
  l = create_logger(out)
635
- l.level =
636
- case get(:log_level)
637
- when /^debug$/i then Logger::DEBUG
638
- when /^info$/i then Logger::INFO
639
- when /^warn$/i then Logger::WARN
640
- when /^error$/i then Logger::ERROR
641
- end
635
+
636
+ if ENV[TRACE_ENV_KEY]
637
+ l.level = Logger::DEBUG
638
+ else
639
+ l.level =
640
+ case get(:log_level)
641
+ when /^debug$/i then Logger::DEBUG
642
+ when /^info$/i then Logger::INFO
643
+ when /^warn$/i then Logger::WARN
644
+ when /^error$/i then Logger::ERROR
645
+ end
646
+ end
642
647
  end
643
648
 
644
649
  l
@@ -118,6 +118,11 @@ module Skylight
118
118
  inst.done(span)
119
119
  end
120
120
 
121
+ def self.broken!
122
+ return unless inst = Instrumenter.instance
123
+ inst.broken!
124
+ end
125
+
121
126
  # Temporarily disable
122
127
  def self.disable
123
128
  unless inst = Instrumenter.instance
@@ -57,15 +57,7 @@ module Skylight
57
57
  end
58
58
 
59
59
  at_exit do
60
- if RUBY_VERSION == '1.9.2'
61
- # workaround for MRI bug losing exit status in at_exit block
62
- # http://bugs.ruby-lang.org/issues/5218
63
- exit_status = $!.status if $!.is_a?(SystemExit)
64
- stop!
65
- exit exit_status if exit_status
66
- else
67
- stop!
68
- end
60
+ stop!
69
61
  end
70
62
 
71
63
  attr_reader :config, :gc, :trace_info
@@ -189,6 +181,11 @@ module Skylight
189
181
  trace.done(span)
190
182
  end
191
183
 
184
+ def broken!
185
+ return unless trace = @trace_info.current
186
+ trace.broken!
187
+ end
188
+
192
189
  def instrument(cat, title=nil, desc=nil)
193
190
  raise ArgumentError, 'cat is required' unless cat
194
191
 
@@ -42,14 +42,14 @@ module Skylight
42
42
  end
43
43
 
44
44
  def self.with_after_close(resp, &block)
45
- # Responses should be finished but in some situations they aren't
45
+ # Responses should be arrays but in some situations they aren't
46
46
  # e.g. https://github.com/ruby-grape/grape/issues/1041
47
- if resp.respond_to?(:finish)
48
- resp = resp.finish
49
- end
47
+ # The safest approach seems to be to rely on implicit destructuring
48
+ # since that is currently what Rack::Lint does.
49
+ # See also https://github.com/rack/rack/issues/1239
50
+ status, headers, body = resp
50
51
 
51
- resp[2] = BodyProxy.new(resp[2], &block)
52
- resp
52
+ [status, headers, BodyProxy.new(body, &block)]
53
53
  end
54
54
 
55
55
  include Util::Logging
@@ -63,13 +63,11 @@ module Skylight
63
63
  end
64
64
 
65
65
  def call(env)
66
- # Skylight can handle double tracing, but avoid the BodyProxy if we don't need it
67
- # This generally shouldn't happen, but older verions of Rails can allow the same
68
- # middleware to be inserted multiple times
69
66
  if Skylight.tracing?
70
- t { "already tracing, skipping" }
71
- @app.call(env)
72
- elsif env["REQUEST_METHOD"] == "HEAD"
67
+ error "Already instrumenting. Make sure the Middleware hasn't been added more than once."
68
+ end
69
+
70
+ if env["REQUEST_METHOD"] == "HEAD"
73
71
  t { "middleware skipping HEAD" }
74
72
  @app.call(env)
75
73
  else
@@ -31,11 +31,16 @@ module Skylight
31
31
  :controller => self.class.name,
32
32
  :action => self.action_name,
33
33
  :params => request.filtered_parameters,
34
- :format => request.format.try(:ref),
35
34
  :method => request.request_method,
36
35
  :path => (request.fullpath rescue "unknown")
37
36
  }
38
37
 
38
+ if Gem::Version.new(Rails.version) < Gem::Version.new('3.1')
39
+ raw_payload[:formats] = request.formats.map(&:to_sym)
40
+ else
41
+ raw_payload[:format] = request.format.try(:ref)
42
+ end
43
+
39
44
  ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
40
45
 
41
46
  ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
@@ -18,11 +18,9 @@ module Skylight
18
18
  layout = nil
19
19
 
20
20
  if path
21
- if method(:find_layout).arity == 3
22
- # Rails 5
21
+ if ::ActionView.respond_to?(:gem_version) && ::ActionView.gem_version >= Gem::Version.new('5.x')
23
22
  layout = find_layout(path, locals.keys, [formats.first])
24
23
  else
25
- # Rails 3, 4
26
24
  layout = find_layout(path, locals.keys)
27
25
  end
28
26
  end
@@ -1,8 +1,55 @@
1
1
  module Skylight
2
2
  module Probes
3
3
  module Middleware
4
+
5
+ def self.add_instrumentation(middleware, default_name="Anonymous Middleware", category="rack.middleware")
6
+ middleware.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
7
+ alias call_without_sk call
8
+ def call(*args, &block)
9
+ trace = Skylight::Instrumenter.try(:instance).try(:current_trace)
10
+ return call_without_sk(*args, &block) unless trace
11
+
12
+ begin
13
+ name = self.class.name || "#{default_name}"
14
+
15
+ trace.endpoint = name
16
+
17
+ span = Skylight.instrument(title: name, category: "#{category}")
18
+ resp = call_without_sk(*args, &block)
19
+
20
+ Skylight::Middleware.with_after_close(resp) { trace.done(span) }
21
+ rescue Exception
22
+ # FIXME: Log this?
23
+ trace.done(span)
24
+ raise
25
+ end
26
+ end
27
+ RUBY
28
+ end
29
+
4
30
  class Probe
31
+
5
32
  def install
33
+ ActionDispatch::MiddlewareStack.class_eval do
34
+ alias build_without_sk build
35
+
36
+ if ::ActionPack.respond_to?(:gem_version) && ::ActionPack.gem_version >= Gem::Version.new('5.x')
37
+ # Rails 5
38
+ def build(app = Proc.new)
39
+ Skylight::Probes::Middleware.add_instrumentation(app, "Rack App", "rack.app")
40
+ build_without_sk(app)
41
+ end
42
+ else
43
+ # Rails 3 and 4
44
+ def build(app, &block)
45
+ app ||= block
46
+ raise "MiddlewareStack#build requires an app" unless app
47
+ Skylight::Probes::Middleware.add_instrumentation(app, "Rack App", "rack.app")
48
+ build_without_sk(app)
49
+ end
50
+ end
51
+ end
52
+
6
53
  ActionDispatch::MiddlewareStack::Middleware.class_eval do
7
54
  alias build_without_sk build
8
55
  def build(*args)
@@ -18,28 +65,7 @@ module Skylight
18
65
  # On Rails 3, ActionDispatch::Session::CookieStore is frozen, for one
19
66
  return middleware if middleware.frozen?
20
67
 
21
- middleware.instance_eval do
22
- alias call_without_sk call
23
- def call(*args, &block)
24
- trace = Skylight::Instrumenter.try(:instance).try(:current_trace)
25
- return call_without_sk(*args, &block) unless trace
26
-
27
- begin
28
- name = self.class.name || "Anonymous Middleware"
29
-
30
- trace.endpoint = name
31
-
32
- span = Skylight.instrument(title: name, category: "rack.middleware")
33
- resp = call_without_sk(*args, &block)
34
-
35
- Skylight::Middleware.with_after_close(resp) { trace.done(span) }
36
- rescue Exception
37
- # FIXME: Log this?
38
- trace.done(span)
39
- raise
40
- end
41
- end
42
- end
68
+ Skylight::Probes::Middleware.add_instrumentation(middleware)
43
69
 
44
70
  middleware
45
71
  end
@@ -47,8 +47,12 @@ module Skylight
47
47
  @instrumenter.config
48
48
  end
49
49
 
50
+ def broken?
51
+ !!@broken
52
+ end
53
+
50
54
  def record(cat, title=nil, desc=nil)
51
- return if @broken
55
+ return if broken?
52
56
 
53
57
  title.freeze if title.is_a?(String)
54
58
  desc.freeze if desc.is_a?(String)
@@ -62,12 +66,12 @@ module Skylight
62
66
  nil
63
67
  rescue => e
64
68
  error "failed to record span; msg=%s", e.message
65
- @broken = true
69
+ broken!
66
70
  nil
67
71
  end
68
72
 
69
73
  def instrument(cat, title=nil, desc=nil)
70
- return if @broken
74
+ return if broken?
71
75
  t { "instrument: #{cat}, #{title}" }
72
76
 
73
77
  title.freeze if title.is_a?(String)
@@ -78,7 +82,8 @@ module Skylight
78
82
  desc = @instrumenter.limited_description(desc)
79
83
 
80
84
  if desc == Instrumenter::TOO_MANY_UNIQUES
81
- debug "[SKYLIGHT] [#{Skylight::VERSION}] A payload description produced <too many uniques>"
85
+ error "[SKYLIGHT] [#{Skylight::VERSION}] [E0002] You've exceeded the number of unique span descriptions per-request " \
86
+ "for endpoint: #{endpoint}."
82
87
  debug "original desc=%s", original_desc
83
88
  debug "cat=%s, title=%s, desc=%s", cat, title, desc
84
89
  end
@@ -86,17 +91,17 @@ module Skylight
86
91
  start(now - gc_time, cat, title, desc)
87
92
  rescue => e
88
93
  error "failed to instrument span; msg=%s", e.message
89
- @broken = true
94
+ broken!
90
95
  nil
91
96
  end
92
97
 
93
98
  def done(span)
94
99
  return unless span
95
- return if @broken
100
+ return if broken?
96
101
  stop(span, Util::Clock.nanos - gc_time)
97
102
  rescue => e
98
103
  error "failed to close span; msg=%s", e.message
99
- @broken = true
104
+ broken!
100
105
  nil
101
106
  end
102
107
 
@@ -105,6 +110,11 @@ module Skylight
105
110
  @instrumenter.current_trace = nil
106
111
  end
107
112
 
113
+ def broken!
114
+ debug "trace is broken"
115
+ @broken = true
116
+ end
117
+
108
118
  def traced
109
119
  time = gc_time
110
120
  now = Util::Clock.nanos
@@ -118,7 +128,7 @@ module Skylight
118
128
  end
119
129
 
120
130
  def submit
121
- return if @broken
131
+ return if broken?
122
132
 
123
133
  t { "submitting trace" }
124
134
 
@@ -158,9 +168,22 @@ module Skylight
158
168
 
159
169
  expected = @spans.pop
160
170
  unless span == expected
161
- error "invalid span nesting"
162
- # TODO: Actually log span title here
163
- t { "expected=#{expected}, actual=#{span}" }
171
+ message = "[E0001] Spans were closed out of order.\n"
172
+
173
+ if Skylight::Util::Logging.trace?
174
+ message << "Expected #{expected}, but received #{span}. See prior logs to match id to a name.\n" \
175
+ "If the received span was a Middleware it may be one that doesn't fully conform to " \
176
+ "the Rack SPEC."
177
+ else
178
+ message << "To debug this issue set `SKYLIGHT_ENABLE_TRACE_LOGS=true` " \
179
+ "in your environment. (Beware, it is quite noisy!)\n"
180
+ end
181
+
182
+ message << "This request will not be tracked. Please contact support@skylight.io for more information."
183
+
184
+ error message
185
+
186
+ broken!
164
187
  end
165
188
 
166
189
  time = self.class.normalize_time(time)
@@ -1,4 +1,4 @@
1
1
  module Skylight
2
- VERSION = '1.5.1'
2
+ VERSION = '1.6.0'
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-07 00:00:00.000000000 Z
11
+ date: 2018-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.4
27
41
  description:
28
42
  email:
29
43
  - engineering@tilde.io
@@ -189,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
189
203
  requirements:
190
204
  - - ">="
191
205
  - !ruby/object:Gem::Version
192
- version: 1.9.2
206
+ version: 1.9.3
193
207
  required_rubygems_version: !ruby/object:Gem::Requirement
194
208
  requirements:
195
209
  - - ">="