skylight 1.4.4 → 1.5.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
  SHA1:
3
- metadata.gz: 14beed2152c9792a9f554eb74f63d5172eb92a11
4
- data.tar.gz: '02378ab496fdf3483f3bef6fc37ec864a7deb0bc'
3
+ metadata.gz: 1a675aa7e9f2f19c9cc336569def0ffcf820876b
4
+ data.tar.gz: 6f9c5b843ef8ffc5a31fa936692468afde1a22c5
5
5
  SHA512:
6
- metadata.gz: 4ea715250be7e1f2c7d7f8a3e6772b3b6ea57f56d305cfb3a1989e2e912f6d560b86fc74d756cea5f4ef72660796427ef55805176183507147680546a256cc4c
7
- data.tar.gz: 80dc5105a4e76dcc9ac625a37260adbbcb2b565ac198fb32d47cf3b7d318a36ef129a41565d0e0ccae8a1c911d550718c056b542a11547b60aea7102577f40ba
6
+ metadata.gz: 31694926e3ab83229d89d13d5ef7605011c7590def3eb31b0f1be0a1830069a95b3bc3e58371b537287c14fa95840426cf6b2624f2082e0ca07dc6d2a00de257
7
+ data.tar.gz: db16281e6cf0ef307e5bf500bcbe58bf0f5e66bf7ebac3d743a81fc6239f291d1740793673e2426a9fe100b2e3aaff3d24c6c4dbaf9d9bfebd1bc80a7f39f748
@@ -1,3 +1,11 @@
1
+ ## 1.5.0 (December 6, 2017)
2
+
3
+ * [FEATURE] [Coach](https://github.com/gocardless/coach) instrumentation. Enabled automatically via ActiveSupport::Notifications.
4
+ * [FEATURE] Option to enable or disable agent by setting SKYLIGHT_ENABLE via ENV.
5
+ * [IMPROVEMENT] Better logging for certain error cases.
6
+ * [BUGFIX] Backport a SPEC compliance fix for older Rack::ETag to resolve case where the Middleware probe could cause empty traces.
7
+ * [BUGFIX] Fix a case where using the non-block form of `Skylight.instrument` with `Skylight.done` could cause lost trace data.
8
+
1
9
  ## 1.4.4 (November 7, 2017)
2
10
 
3
11
  * [BUGFIX] The minimum glibc requirement was errorneously bumped to 2.15. We have returned it to 2.5.
@@ -45,3 +45,32 @@ if defined?(ActiveSupport::Notifications::Fanout::Subscribers::Evented)
45
45
  end
46
46
  end
47
47
  end
48
+
49
+ require 'rack'
50
+ require 'rack/etag'
51
+ if Rack.release.to_f < 1.6
52
+ # Backport `close` compliance:
53
+ # https://github.com/rack/rack/commit/4d9e1b228dacbcf1552c68e2ab2f21274fdcecb4
54
+ Rack::ETag.class_eval do
55
+ def call(env)
56
+ status, headers, body = @app.call(env)
57
+
58
+ if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
59
+ original_body = body
60
+ digest, body = digest_body(body)
61
+ original_body.close if original_body.respond_to?(:close)
62
+ headers['ETag'] = %("#{digest}") if digest
63
+ end
64
+
65
+ unless headers['Cache-Control']
66
+ if digest
67
+ headers['Cache-Control'] = @cache_control if @cache_control
68
+ else
69
+ headers['Cache-Control'] = @no_cache_control if @no_cache_control
70
+ end
71
+ end
72
+
73
+ [status, headers, body]
74
+ end
75
+ end
76
+ end
@@ -89,12 +89,6 @@ module Skylight
89
89
  end
90
90
  end
91
91
 
92
- # End a trace
93
- def self.done(span)
94
- return unless inst = Instrumenter.instance
95
- inst.done(span)
96
- end
97
-
98
92
  # Instrument
99
93
  def self.instrument(opts = DEFAULT_OPTIONS, &block)
100
94
  unless inst = Instrumenter.instance
@@ -118,6 +112,12 @@ module Skylight
118
112
  inst.instrument(category, title, desc, &block)
119
113
  end
120
114
 
115
+ # End a span
116
+ def self.done(span)
117
+ return unless inst = Instrumenter.instance
118
+ inst.done(span)
119
+ end
120
+
121
121
  # Temporarily disable
122
122
  def self.disable
123
123
  unless inst = Instrumenter.instance
@@ -26,7 +26,8 @@ module Skylight
26
26
  @closed
27
27
  end
28
28
 
29
- # N.B. This method is a special case to address the bug described by #434.
29
+ # N.B. This method is a special case to address the bug described by
30
+ # https://github.com/rack/rack/issues/434.
30
31
  # We are applying this special case for #each only. Future bugs of this
31
32
  # class will be handled by requesting users to patch their ruby
32
33
  # implementation, to save adding too many methods in this class.
@@ -86,9 +87,6 @@ module Skylight
86
87
  t { "middleware exception: #{trace}"}
87
88
  trace.submit if trace
88
89
  raise
89
- ensure
90
- t { "middleware release: #{trace}"}
91
- trace.release if trace
92
90
  end
93
91
  end
94
92
  end
@@ -160,6 +160,13 @@ module Skylight
160
160
  require "skylight/normalizers/#{file}"
161
161
  end
162
162
 
163
+ # Coach instrumentation is only available in Ruby 2+
164
+ if RUBY_VERSION.split.first.to_i > 1
165
+ %w(coach/handler_finish coach/middleware_finish).each do |file|
166
+ require "skylight/normalizers/#{file}"
167
+ end
168
+ end
169
+
163
170
  # The following are not required by default as they are of dubious usefulness:
164
171
  # - active_job/enqueue_at
165
172
  end
@@ -0,0 +1,36 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Coach
4
+ class HandlerFinish < Normalizer
5
+ register "coach.handler.finish"
6
+
7
+ CAT = "app.coach.handler".freeze
8
+
9
+ # See information on the events Coach emits here:
10
+ # https://github.com/gocardless/coach#instrumentation
11
+
12
+ # Run when the handler first starts, we need to set the trace endpoint to be the
13
+ # handler name.
14
+ #
15
+ # We can expect the payload to have the :middleware key.
16
+ def normalize(trace, name, payload)
17
+ trace.endpoint = payload[:middleware]
18
+ [ CAT, payload[:middleware], nil ]
19
+ end
20
+
21
+ def normalize_after(trace, span, name, payload)
22
+ return unless config.enable_segments?
23
+
24
+ segments = []
25
+
26
+ response_status = payload.fetch(:response, {}).fetch(:status, '').to_s
27
+ segments << "error" if response_status.start_with?('4', '5')
28
+
29
+ if segments.any?
30
+ trace.endpoint += "<sk-segment>#{segments.join("+")}</sk-segment>"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Coach
4
+ class MiddlewareFinish < Normalizer
5
+ register "coach.middleware.finish"
6
+
7
+ CAT = "app.coach.middleware".freeze
8
+
9
+ # See information on the events Coach emits here:
10
+ # https://github.com/gocardless/coach#instrumentation
11
+
12
+ # Called whenever a new middleware is executed. We can expect this to happen
13
+ # within a Coach::Handler.
14
+ #
15
+ # We can expect the payload to have the :middleware key.
16
+ def normalize(trace, name, payload)
17
+ trace.endpoint = payload[:middleware]
18
+ [ CAT, payload[:middleware], nil ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -28,6 +28,8 @@ module Skylight
28
28
  uri.host, uri.port, uri.path, uri.query)
29
29
  description = opts[:title]
30
30
 
31
+ # We use "Faraday" as the title to differentiate it in the UI in
32
+ # case it's wrapping or is wrapped by another HTTP backend
31
33
  [opts[:category], "Faraday", description]
32
34
  end
33
35
  end
@@ -117,7 +117,11 @@ module Skylight
117
117
  end
118
118
 
119
119
  def activate?
120
- environments.include?(Rails.env.to_s)
120
+ if ENV.key?("SKYLIGHT_ENABLED")
121
+ ENV["SKYLIGHT_ENABLED"] !~ /^false$/i
122
+ else
123
+ environments.include?(Rails.env.to_s)
124
+ end
121
125
  end
122
126
 
123
127
  def load_probes
@@ -29,6 +29,8 @@ module Skylight
29
29
 
30
30
  @notifications = []
31
31
 
32
+ @spans = []
33
+
32
34
  # create the root node
33
35
  @root = start(native_get_started_at, cat, title, desc, normalize: false)
34
36
 
@@ -132,7 +134,7 @@ module Skylight
132
134
 
133
135
  @instrumenter.process(self)
134
136
  rescue Exception => e
135
- error e
137
+ error e.message
136
138
  t { e.backtrace.join("\n") }
137
139
  end
138
140
 
@@ -144,10 +146,22 @@ module Skylight
144
146
  sp = native_start_span(time, cat.to_s)
145
147
  native_span_set_title(sp, title.to_s) if title
146
148
  native_span_set_description(sp, desc.to_s) if desc
149
+
150
+ @spans << sp
151
+ t { "started span: #{sp} - #{cat}, #{title}" }
152
+
147
153
  sp
148
154
  end
149
155
 
150
156
  def stop(span, time)
157
+ t { "stopping span: #{span}" }
158
+
159
+ expected = @spans.pop
160
+ unless span == expected
161
+ error "invalid span nesting"
162
+ t { "expected=#{expected}, actual=#{span}" }
163
+ end
164
+
151
165
  time = self.class.normalize_time(time)
152
166
  native_stop_span(span, time)
153
167
  nil
@@ -78,8 +78,8 @@ module Skylight
78
78
  # @param msg (see #log)
79
79
  # @param args (see #log)
80
80
  def error(msg, *args)
81
- raise sprintf(msg, *args) if ENV['SKYLIGHT_RAISE_ON_ERROR']
82
81
  log :error, msg, *args
82
+ raise sprintf(msg, *args) if ENV['SKYLIGHT_RAISE_ON_ERROR']
83
83
  end
84
84
 
85
85
  alias log_trace trace
@@ -1,4 +1,4 @@
1
1
  module Skylight
2
- VERSION = '1.4.4'
2
+ VERSION = '1.5.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.4.4
4
+ version: 1.5.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: 2017-11-07 00:00:00.000000000 Z
11
+ date: 2017-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,8 @@ files:
80
80
  - lib/skylight/normalizers/active_support/cache_read.rb
81
81
  - lib/skylight/normalizers/active_support/cache_read_multi.rb
82
82
  - lib/skylight/normalizers/active_support/cache_write.rb
83
+ - lib/skylight/normalizers/coach/handler_finish.rb
84
+ - lib/skylight/normalizers/coach/middleware_finish.rb
83
85
  - lib/skylight/normalizers/couch_potato/query.rb
84
86
  - lib/skylight/normalizers/default.rb
85
87
  - lib/skylight/normalizers/elasticsearch/request.rb