skylight 1.7.2 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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