skylight 1.7.2 → 2.0.0.beta1

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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -33
  3. data/ext/extconf.rb +32 -6
  4. data/ext/libskylight.yml +6 -9
  5. data/ext/skylight_native.c +49 -18
  6. data/lib/skylight.rb +35 -1
  7. data/lib/skylight/api.rb +4 -2
  8. data/lib/skylight/cli.rb +1 -1
  9. data/lib/skylight/cli/doctor.rb +6 -4
  10. data/lib/skylight/config.rb +149 -518
  11. data/lib/skylight/data/cacert.pem +236 -812
  12. data/lib/skylight/helpers.rb +5 -1
  13. data/lib/skylight/instrumenter.rb +10 -241
  14. data/lib/skylight/middleware.rb +1 -89
  15. data/lib/skylight/native.rb +8 -6
  16. data/lib/skylight/native_ext_fetcher.rb +251 -0
  17. data/lib/skylight/normalizers/active_job/enqueue_at.rb +2 -20
  18. data/lib/skylight/probes/sinatra_add_middleware.rb +22 -0
  19. data/lib/skylight/railtie.rb +11 -131
  20. data/lib/skylight/sinatra.rb +1 -5
  21. data/lib/skylight/trace.rb +1 -229
  22. data/lib/skylight/util/http.rb +3 -3
  23. data/lib/skylight/vendor/cli/thor/actions/directory.rb +5 -15
  24. data/lib/skylight/version.rb +1 -1
  25. metadata +114 -91
  26. data/lib/skylight/compat.rb +0 -76
  27. data/lib/skylight/core.rb +0 -149
  28. data/lib/skylight/deprecation.rb +0 -55
  29. data/lib/skylight/formatters/http.rb +0 -20
  30. data/lib/skylight/gc.rb +0 -107
  31. data/lib/skylight/normalizers.rb +0 -192
  32. data/lib/skylight/normalizers/action_controller/process_action.rb +0 -50
  33. data/lib/skylight/normalizers/action_controller/send_file.rb +0 -50
  34. data/lib/skylight/normalizers/action_view/render_collection.rb +0 -22
  35. data/lib/skylight/normalizers/action_view/render_partial.rb +0 -21
  36. data/lib/skylight/normalizers/action_view/render_template.rb +0 -21
  37. data/lib/skylight/normalizers/active_model_serializers/render.rb +0 -26
  38. data/lib/skylight/normalizers/active_record/instantiation.rb +0 -17
  39. data/lib/skylight/normalizers/active_record/sql.rb +0 -55
  40. data/lib/skylight/normalizers/active_support/cache.rb +0 -51
  41. data/lib/skylight/normalizers/active_support/cache_clear.rb +0 -16
  42. data/lib/skylight/normalizers/active_support/cache_decrement.rb +0 -16
  43. data/lib/skylight/normalizers/active_support/cache_delete.rb +0 -16
  44. data/lib/skylight/normalizers/active_support/cache_exist.rb +0 -16
  45. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +0 -16
  46. data/lib/skylight/normalizers/active_support/cache_generate.rb +0 -16
  47. data/lib/skylight/normalizers/active_support/cache_increment.rb +0 -16
  48. data/lib/skylight/normalizers/active_support/cache_read.rb +0 -16
  49. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +0 -16
  50. data/lib/skylight/normalizers/active_support/cache_write.rb +0 -16
  51. data/lib/skylight/normalizers/coach/handler_finish.rb +0 -36
  52. data/lib/skylight/normalizers/coach/middleware_finish.rb +0 -23
  53. data/lib/skylight/normalizers/couch_potato/query.rb +0 -20
  54. data/lib/skylight/normalizers/default.rb +0 -27
  55. data/lib/skylight/normalizers/elasticsearch/request.rb +0 -20
  56. data/lib/skylight/normalizers/faraday/request.rb +0 -38
  57. data/lib/skylight/normalizers/grape/endpoint.rb +0 -30
  58. data/lib/skylight/normalizers/grape/endpoint_render.rb +0 -26
  59. data/lib/skylight/normalizers/grape/endpoint_run.rb +0 -33
  60. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +0 -23
  61. data/lib/skylight/normalizers/moped/query.rb +0 -100
  62. data/lib/skylight/probes.rb +0 -129
  63. data/lib/skylight/probes/action_controller.rb +0 -64
  64. data/lib/skylight/probes/action_dispatch.rb +0 -30
  65. data/lib/skylight/probes/action_view.rb +0 -43
  66. data/lib/skylight/probes/active_model_serializers.rb +0 -55
  67. data/lib/skylight/probes/elasticsearch.rb +0 -37
  68. data/lib/skylight/probes/excon.rb +0 -26
  69. data/lib/skylight/probes/excon/middleware.rb +0 -68
  70. data/lib/skylight/probes/faraday.rb +0 -22
  71. data/lib/skylight/probes/grape.rb +0 -88
  72. data/lib/skylight/probes/httpclient.rb +0 -46
  73. data/lib/skylight/probes/middleware.rb +0 -68
  74. data/lib/skylight/probes/mongo.rb +0 -161
  75. data/lib/skylight/probes/mongoid.rb +0 -21
  76. data/lib/skylight/probes/moped.rb +0 -39
  77. data/lib/skylight/probes/net_http.rb +0 -58
  78. data/lib/skylight/probes/redis.rb +0 -71
  79. data/lib/skylight/probes/sequel.rb +0 -37
  80. data/lib/skylight/probes/sinatra.rb +0 -76
  81. data/lib/skylight/probes/tilt.rb +0 -31
  82. data/lib/skylight/subscriber.rb +0 -122
  83. data/lib/skylight/user_config.rb +0 -60
  84. data/lib/skylight/util.rb +0 -17
  85. data/lib/skylight/util/allocation_free.rb +0 -26
  86. data/lib/skylight/util/clock.rb +0 -54
  87. data/lib/skylight/util/deploy.rb +0 -132
  88. data/lib/skylight/util/gzip.rb +0 -21
  89. data/lib/skylight/util/inflector.rb +0 -112
  90. data/lib/skylight/util/logging.rb +0 -127
  91. data/lib/skylight/util/multi_io.rb +0 -21
  92. data/lib/skylight/util/native_ext_fetcher.rb +0 -253
  93. data/lib/skylight/util/platform.rb +0 -75
  94. data/lib/skylight/util/proxy.rb +0 -13
  95. data/lib/skylight/vendor/active_support/notifications.rb +0 -207
  96. data/lib/skylight/vendor/active_support/notifications/fanout.rb +0 -159
  97. data/lib/skylight/vendor/active_support/notifications/instrumenter.rb +0 -72
  98. data/lib/skylight/vendor/active_support/per_thread_registry.rb +0 -52
  99. data/lib/skylight/vendor/thread_safe.rb +0 -126
  100. data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +0 -133
  101. data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +0 -76
  102. data/lib/skylight/vm/gc.rb +0 -70
@@ -1,21 +1,3 @@
1
- module Skylight
2
- module Normalizers
3
- module ActiveJob
4
- class EnqueueAt < Normalizer
5
- register "enqueue_at.active_job", enabled: false
1
+ warn "[DEPRECATED] [SKYLIGHT] [#{Skylight::VERSION}] Require 'skylight/core/normalizers/active_job/enqueue_at' instead of 'skylight/normalizers/active_job/enqueue_at'."
6
2
 
7
- CAT = "other.job.enqueue_at".freeze
8
-
9
- def normalize(_trace, _name, payload)
10
- title = "Enqueue #{payload[:job].class}"
11
-
12
- adapter_class_name = payload[:adapter].class.name
13
- adapter_name = adapter_class_name.match(/^ActiveJob::QueueAdapters::(\w+)Adapter$/)[1].underscore
14
- desc = "{ adapter: '#{adapter_name}', queue: '#{payload[:job].queue_name}' }"
15
-
16
- [ CAT, title, desc ]
17
- end
18
- end
19
- end
20
- end
21
- end
3
+ require 'skylight/core/normalizers/active_job/enqueue_at'
@@ -0,0 +1,22 @@
1
+ module Skylight
2
+ module Probes
3
+ module Sinatra
4
+ class Probe
5
+ def install
6
+ puts "Installed"
7
+ class << ::Sinatra::Base
8
+ alias build_without_sk build
9
+
10
+ def build(*args, &block)
11
+ puts "Using Middleware"
12
+ self.use Skylight::Middleware
13
+ build_without_sk(*args, &block)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Skylight::Core::Probes.register("Sinatra::Base", "sinatra/base", Sinatra::Probe.new)
21
+ end
22
+ end
@@ -1,9 +1,12 @@
1
- require 'skylight'
2
- require 'rails'
1
+ require 'skylight/core/railtie'
3
2
 
4
3
  module Skylight
5
- # @api private
6
4
  class Railtie < Rails::Railtie
5
+ include Skylight::Core::Railtie
6
+
7
+ def self.config_class; Skylight::Config end
8
+ def self.middleware_class; Skylight::Middleware end
9
+
7
10
  config.skylight = ActiveSupport::OrderedOptions.new
8
11
 
9
12
  # The environments in which skylight should be enabled
@@ -16,144 +19,21 @@ module Skylight
16
19
  # net_http, action_controller, action_view, middleware, and grape are on by default
17
20
  # See https://www.skylight.io/support/getting-more-from-skylight#available-instrumentation-options
18
21
  # for a full list.
19
- config.skylight.probes = ['net_http', 'action_dispatch', 'action_controller', 'action_view', 'middleware', 'grape']
22
+ config.skylight.probes = ['net_http', 'action_controller', 'action_view', 'middleware', 'grape']
20
23
 
21
24
  # The position in the middleware stack to place Skylight
22
25
  # Default is first, but can be `{ after: Middleware::Name }` or `{ before: Middleware::Name }`
23
26
  config.skylight.middleware_position = 0
24
27
 
25
28
  initializer 'skylight.configure' do |app|
26
- # Load probes even when agent is inactive to catch probe related bugs sooner
27
- load_probes
28
-
29
- config = load_skylight_config(app)
30
-
31
- if activate?
32
- if config
33
- begin
34
- if Instrumenter.start!(config)
35
- set_middleware_position(app, config)
36
- Rails.logger.info "[SKYLIGHT] [#{Skylight::VERSION}] Skylight agent enabled"
37
- else
38
- Rails.logger.info "[SKYLIGHT] [#{Skylight::VERSION}] Unable to start, see the Skylight logs for more details"
39
- end
40
- rescue ConfigError => e
41
- Rails.logger.error "[SKYLIGHT] [#{Skylight::VERSION}] #{e.message}; disabling Skylight agent"
42
- end
43
- end
44
- elsif Rails.env.development?
45
- unless config.user_config.disable_dev_warning?
46
- log_warning config, "[SKYLIGHT] [#{Skylight::VERSION}] Running Skylight in development mode. No data will be reported until you deploy your app.\n" \
47
- "(To disable this message for all local apps, run `skylight disable_dev_warning`.)"
48
- end
49
- elsif !Rails.env.test?
50
- unless config.user_config.disable_env_warning?
51
- log_warning config, "[SKYLIGHT] [#{Skylight::VERSION}] You are running in the #{Rails.env} environment but haven't added it to config.skylight.environments, so no data will be sent to skylight.io."
52
- end
53
- end
54
- end
55
-
56
- private
57
-
58
- def log_warning(config, msg)
59
- if config
60
- config.alert_logger.warn(msg)
61
- else
62
- Rails.logger.warn(msg)
63
- end
64
- end
65
-
66
- def existent_paths(paths)
67
- paths.respond_to?(:existent) ? paths.existent : paths.select { |f| File.exists?(f) }
68
- end
69
-
70
- def load_skylight_config(app)
71
- path = config_path(app)
72
- path = nil unless File.exist?(path)
73
-
74
- unless tmp = app.config.paths['tmp'].first
75
- Rails.logger.error "[SKYLIGHT] [#{Skylight::VERSION}] tmp directory missing from rails configuration"
76
- return nil
77
- end
78
-
79
- config = Config.load(file: path, environment: Rails.env.to_s)
80
- config[:root] = Rails.root
81
-
82
- configure_logging(config, app)
83
-
84
- config[:'daemon.sockdir_path'] ||= tmp
85
- config[:'normalizers.render.view_paths'] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
86
- config
29
+ run_initializer(app)
87
30
  end
88
31
 
89
- def configure_logging(config, app)
90
- if logger = app.config.skylight.logger
91
- config.logger = logger
92
- else
93
- # Configure the log file destination
94
- if log_file = app.config.skylight.log_file
95
- config['log_file'] = log_file
96
- elsif !config.key?('log_file') && !config.on_heroku?
97
- config['log_file'] = File.join(Rails.root, 'log/skylight.log')
98
- end
32
+ private
99
33
 
100
- # Configure the log level
101
- if level = app.config.skylight.log_level
102
- config['log_level'] = level
103
- elsif !config.key?('log_level')
104
- if level = app.config.log_level
105
- config['log_level'] = level
106
- end
107
- end
34
+ def development_warning
35
+ super + "\n(To disable this message for all local apps, run `skylight disable_dev_warning`.)"
108
36
  end
109
- end
110
-
111
- def config_path(app)
112
- File.expand_path(config.skylight.config_path, app.root)
113
- end
114
-
115
- def environments
116
- Array(config.skylight.environments).map { |e| e && e.to_s }.compact
117
- end
118
-
119
- def activate?
120
- if ENV.key?("SKYLIGHT_ENABLED")
121
- ENV["SKYLIGHT_ENABLED"] !~ /^false$/i
122
- else
123
- environments.include?(Rails.env.to_s)
124
- end
125
- end
126
-
127
- def load_probes
128
- if probes = config.skylight.probes
129
- Skylight.probe(*probes)
130
- end
131
- end
132
37
 
133
- def middleware_position
134
- config.skylight.middleware_position.is_a?(Hash) ? config.skylight.middleware_position.symbolize_keys : config.skylight.middleware_position
135
- end
136
-
137
- def insert_middleware(app, config)
138
- if middleware_position.has_key?(:after)
139
- app.middleware.insert_after(middleware_position[:after], Skylight::Middleware, config: config)
140
- elsif middleware_position.has_key?(:before)
141
- app.middleware.insert_before(middleware_position[:before], Skylight::Middleware, config: config)
142
- else
143
- raise "The middleware position you have set is invalid. Please be sure `config.skylight.middleware_position` is set up correctly."
144
- end
145
- end
146
-
147
- def set_middleware_position(app, config)
148
- if middleware_position.is_a?(Integer)
149
- app.middleware.insert middleware_position, Middleware, config: config
150
- elsif middleware_position.is_a?(Hash) && middleware_position.keys.count == 1
151
- insert_middleware(app, config)
152
- elsif middleware_position.nil?
153
- app.middleware.insert 0, Middleware, config: config
154
- else
155
- raise "The middleware position you have set is invalid. Please be sure `config.skylight.middleware_position` is set up correctly."
156
- end
157
- end
158
38
  end
159
39
  end
@@ -1,7 +1,3 @@
1
1
  require 'skylight'
2
-
3
- if Gem::Version(Sinatra::VERSION) < Gem::Version('1.4')
4
- Skylight::DEPRECATOR.deprecation_warning("Support for Sinatra versions before 1.4")
5
- end
6
-
2
+ require 'skylight/probes/sinatra_add_middleware'
7
3
  Skylight.probe(:sinatra, :tilt, :sequel)
@@ -1,232 +1,4 @@
1
1
  module Skylight
2
- class Trace
3
- GC_CAT = 'noise.gc'.freeze
4
-
5
- include Util::Logging
6
-
7
- attr_reader :endpoint, :notifications
8
-
9
- def self.new(instrumenter, endpoint, start, cat, title = nil, desc = nil)
10
- inst = native_new(normalize_time(start), "TODO", endpoint)
11
- inst.send(:initialize, instrumenter, cat, title, desc)
12
- inst.endpoint = endpoint
13
- inst
14
- end
15
-
16
- # TODO: Move this into native
17
- def self.normalize_time(time)
18
- # At least one customer has extensions that cause integer division to produce rationals.
19
- # Since the native code expects an integer, we force it again.
20
- (time.to_i / 100_000).to_i
21
- end
22
-
23
- def initialize(instrumenter, cat, title, desc)
24
- raise ArgumentError, 'instrumenter is required' unless instrumenter
25
-
26
- @instrumenter = instrumenter
27
- @submitted = false
28
- @broken = false
29
-
30
- @notifications = []
31
-
32
- @spans = []
33
-
34
- # create the root node
35
- @root = start(native_get_started_at, cat, title, desc, normalize: false)
36
-
37
- @gc = config.gc.track unless ENV.key?("SKYLIGHT_DISABLE_GC_TRACKING")
38
- end
39
-
40
- def endpoint=(value)
41
- @endpoint = value
42
- native_set_endpoint(value)
43
- value
44
- end
45
-
46
- def config
47
- @instrumenter.config
48
- end
49
-
50
- def broken?
51
- !!@broken
52
- end
53
-
54
- def record(cat, title=nil, desc=nil)
55
- return if broken?
56
-
57
- title.freeze if title.is_a?(String)
58
- desc.freeze if desc.is_a?(String)
59
-
60
- desc = @instrumenter.limited_description(desc)
61
-
62
- time = Util::Clock.nanos - gc_time
63
-
64
- stop(start(time, cat, title, desc), time)
65
-
66
- nil
67
- rescue => e
68
- error "failed to record span; msg=%s; endpoint=%s", e.message, endpoint
69
- broken!
70
- nil
71
- end
72
-
73
- def instrument(cat, title=nil, desc=nil)
74
- return if broken?
75
- t { "instrument: #{cat}, #{title}" }
76
-
77
- title.freeze if title.is_a?(String)
78
- desc.freeze if desc.is_a?(String)
79
-
80
- original_desc = desc
81
- now = Util::Clock.nanos
82
- desc = @instrumenter.limited_description(desc)
83
-
84
- if desc == Instrumenter::TOO_MANY_UNIQUES
85
- error "[SKYLIGHT] [#{Skylight::VERSION}] [E0002] You've exceeded the number of unique span descriptions per-request " \
86
- "for endpoint: #{endpoint}."
87
- debug "original desc=%s", original_desc
88
- debug "cat=%s, title=%s, desc=%s", cat, title, desc
89
- end
90
-
91
- start(now - gc_time, cat, title, desc)
92
- rescue => e
93
- error "failed to instrument span; msg=%s; endpoint=%s", e.message, endpoint
94
- broken!
95
- nil
96
- end
97
-
98
- def done(span, meta=nil)
99
- return unless span
100
- return if broken?
101
-
102
- if meta && meta[:defer]
103
- deferred_spans[span] ||= (Util::Clock.nanos - gc_time)
104
- return
105
- end
106
-
107
- stop(span, Util::Clock.nanos - gc_time)
108
- rescue => e
109
- error "failed to close span; msg=%s; endpoint=%s", e.message, endpoint
110
- broken!
111
- nil
112
- end
113
-
114
- # Middleware spans that were interrupted by a throw/catch should be cached here.
115
- # keys: span ids
116
- # values: nsec timestamp at which the span was cached here.
117
- def deferred_spans
118
- @deferred_spans ||= {}
119
- end
120
-
121
- def release
122
- return unless @instrumenter.current_trace == self
123
- @instrumenter.current_trace = nil
124
- end
125
-
126
- def broken!
127
- debug "trace is broken"
128
- @broken = true
129
- end
130
-
131
- def traced
132
- time = gc_time
133
- now = Util::Clock.nanos
134
-
135
- if time > 0
136
- t { fmt "tracking GC time; duration=%d", time }
137
- stop(start(now - time, GC_CAT, nil, nil), now)
138
- end
139
-
140
- stop(@root, now)
141
- end
142
-
143
- def submit
144
- t { "submitting trace" }
145
-
146
- # This must always be called to clean up properly
147
- release
148
-
149
- if broken?
150
- t { "broken, not submitting" }
151
- return
152
- end
153
-
154
- if @submitted
155
- t { "already submitted" }
156
- return
157
- end
158
-
159
- @submitted = true
160
-
161
- traced
162
-
163
- @instrumenter.process(self)
164
- rescue Exception => e
165
- error e.message
166
- t { e.backtrace.join("\n") }
167
- end
168
-
169
- private
170
-
171
- def start(time, cat, title, desc, opts={})
172
- time = self.class.normalize_time(time) unless opts[:normalize] == false
173
-
174
- sp = native_start_span(time, cat.to_s)
175
- native_span_set_title(sp, title.to_s) if title
176
- native_span_set_description(sp, desc.to_s) if desc
177
-
178
- @spans << sp
179
- t { "started span: #{sp} - #{cat}, #{title}" }
180
-
181
- sp
182
- end
183
-
184
- def stop(span, time)
185
- t { "stopping span: #{span}" }
186
-
187
- # If `stop` is called for a span that is not the last item in the stack,
188
- # check to see if the last item has been marked as deferred. If so, close
189
- # that span first, then try to close the original.
190
- while deferred_spans[expected = @spans.pop]
191
- normalized_stop(expected, deferred_spans.delete(expected))
192
- end
193
-
194
- handle_unexpected_stop(expected, span) unless span == expected
195
-
196
- normalized_stop(span, time)
197
- nil
198
- end
199
-
200
- def normalized_stop(span, time)
201
- time = self.class.normalize_time(time)
202
- native_stop_span(span, time)
203
- end
204
-
205
- def handle_unexpected_stop(expected, span)
206
- message = "[E0001] Spans were closed out of order.\n"
207
-
208
- if Skylight::Util::Logging.trace?
209
- message << "Expected #{expected}, but received #{span}. See prior logs to match id to a name.\n" \
210
- "If the received span was a Middleware it may be one that doesn't fully conform to " \
211
- "the Rack SPEC."
212
- else
213
- message << "To debug this issue set `SKYLIGHT_ENABLE_TRACE_LOGS=true` " \
214
- "in your environment. (Beware, it is quite noisy!)\n"
215
- end
216
-
217
- message << "\nThis request will not be tracked. Please contact support@skylight.io for more information."
218
-
219
- error message
220
-
221
- t { "expected=#{expected}, actual=#{span}" }
222
-
223
- broken!
224
- end
225
-
226
- def gc_time
227
- return 0 unless @gc
228
- @gc.update
229
- @gc.time
230
- end
2
+ class Trace < Core::Trace
231
3
  end
232
4
  end