skylight 1.5.1 → 1.6.0

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: 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
  - - ">="