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,68 +0,0 @@
1
- module Skylight
2
- module Probes
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
- proxied_response = Skylight::Middleware.with_after_close(resp) do
21
- trace.done(span)
22
- end
23
- rescue Exception => err
24
- # FIXME: Log this?
25
- trace.done(span, exception_object: err)
26
- raise
27
- ensure
28
- unless err || proxied_response
29
- # If we've gotten to this point, the most likely scenario is that
30
- # a throw/catch has bypassed a portion of the callstack. Since these spans would not otherwise
31
- # be closed, mark them deferred to indicate that they should be implicitly closed.
32
- # See Core::Trace#deferred_spans or Core::Trace#stop for more information.
33
- trace.done(span, defer: true)
34
- end
35
- end
36
- end
37
- RUBY
38
- end
39
-
40
- class Probe
41
- def install
42
- ::ActionDispatch::MiddlewareStack::Middleware.class_eval do
43
- alias build_without_sk build
44
- def build(*args)
45
- sk_instrument_middleware(build_without_sk(*args))
46
- end
47
-
48
- def sk_instrument_middleware(middleware)
49
- return middleware if middleware.is_a?(Skylight::Middleware)
50
-
51
- # Not sure how this would actually happen
52
- return middleware if middleware.respond_to?(:call_without_sk)
53
-
54
- # On Rails 3, ActionDispatch::Session::CookieStore is frozen, for one
55
- return middleware if middleware.frozen?
56
-
57
- Skylight::Probes::Middleware.add_instrumentation(middleware)
58
-
59
- middleware
60
- end
61
- end
62
- end
63
- end
64
- end
65
-
66
- register(:middleware, "ActionDispatch::MiddlewareStack::Middleware", "actionpack/action_dispatch", Middleware::Probe.new)
67
- end
68
- end
@@ -1,161 +0,0 @@
1
- module Skylight
2
- module Probes
3
- module Mongo
4
- CAT = "db.mongo.command".freeze
5
-
6
- class Probe
7
- def install
8
- ::Mongo::Monitoring::Global.subscribe(::Mongo::Monitoring::COMMAND, Subscriber.new)
9
- end
10
- end
11
-
12
- class Subscriber
13
- include Skylight::Util::Logging
14
-
15
- COMMANDS = [:insert, :find, :count, :distinct, :update, :findandmodify, :delete].freeze
16
-
17
- COMMAND_NAMES = {
18
- findandmodify: 'findAndModify'.freeze
19
- }.freeze
20
-
21
- def initialize
22
- @events = {}
23
- end
24
-
25
- def started(event)
26
- begin_instrumentation(event)
27
- end
28
-
29
- def succeeded(event)
30
- end_instrumentation(event)
31
- end
32
-
33
- def failed(event)
34
- end_instrumentation(event)
35
- end
36
-
37
- # For logging
38
- def config
39
- instrumenter = Skylight::Instrumenter.instance
40
- instrumenter ? instrumenter.config : nil
41
- end
42
-
43
- private
44
-
45
- def begin_instrumentation(event)
46
- return unless COMMANDS.include?(event.command_name.to_sym)
47
-
48
- command_name = COMMAND_NAMES[event.command_name] || event.command_name
49
-
50
- title = "#{event.database_name}.#{command_name}"
51
-
52
- command = event.command
53
-
54
- # Not sure if this will always exist
55
- # Delete so the description will be less redundant
56
- if target = command[event.command_name]
57
- title << " #{target}"
58
- end
59
-
60
- payload = {}
61
-
62
- # Ruby Hashes are ordered based on insertion so do the most important ones first
63
-
64
- add_value('key'.freeze, command, payload)
65
- add_bound('query'.freeze, command, payload)
66
- add_bound('filter'.freeze, command, payload)
67
- add_value('sort'.freeze, command, payload)
68
-
69
- if event.command_name == :findandmodify
70
- add_bound('update'.freeze, command, payload)
71
- end
72
-
73
- add_value('remove'.freeze, command, payload)
74
- add_value('new'.freeze, command, payload)
75
-
76
- if updates = command['updates'.freeze]
77
- # AFAICT the gem generally just sends one item in the updates array
78
- update = updates[0]
79
- update_payload = {}
80
- add_bound('q'.freeze, update, update_payload)
81
- add_bound('u'.freeze, update, update_payload)
82
- add_value('multi'.freeze, update, update_payload)
83
- add_value('upsert'.freeze, update, update_payload)
84
-
85
- payload['updates'.freeze] = [update_payload]
86
-
87
- if updates.length > 1
88
- payload['updates'.freeze] << '...'
89
- end
90
- end
91
-
92
- if deletes = command['deletes'.freeze]
93
- # AFAICT the gem generally just sends one item in the updates array
94
- delete = deletes[0]
95
- delete_payload = {}
96
- add_bound('q'.freeze, delete, delete_payload)
97
- add_value('limit'.freeze, delete, delete_payload)
98
-
99
- payload['deletes'.freeze] = [delete_payload]
100
-
101
- if deletes.length > 1
102
- payload['deletes'.freeze] << '...'
103
- end
104
- end
105
-
106
-
107
- # We're ignoring documents from insert because they could have completely inconsistent
108
- # format which would make it hard to merge.
109
-
110
- opts = {
111
- category: CAT,
112
- title: title,
113
- description: payload.empty? ? nil : payload.to_json
114
- }
115
-
116
- @events[event.operation_id] = Skylight.instrument(opts)
117
- rescue Exception => e
118
- error "failed to begin instrumentation for Mongo; msg=%s", e.message
119
- end
120
-
121
- def end_instrumentation(event)
122
- if original_event = @events.delete(event.operation_id)
123
- Skylight.done(original_event)
124
- end
125
- rescue Exception => e
126
- error "failed to end instrumentation for Mongo; msg=%s", e.message
127
- end
128
-
129
- def add_value(key, command, payload)
130
- if command.has_key?(key)
131
- value = command[key]
132
- payload[key] = value
133
- end
134
- end
135
-
136
- def add_bound(key, command, payload)
137
- if value = command[key]
138
- payload[key] = extract_binds(value)
139
- end
140
- end
141
-
142
- def extract_binds(hash)
143
- ret = {}
144
-
145
- hash.each do |k,v|
146
- if v.is_a?(Hash)
147
- ret[k] = extract_binds(v)
148
- else
149
- ret[k] = '?'.freeze
150
- end
151
- end
152
-
153
- ret
154
- end
155
-
156
- end
157
- end
158
-
159
- register(:mongo, "Mongo", "mongo", Mongo::Probe.new)
160
- end
161
- end
@@ -1,21 +0,0 @@
1
- module Skylight
2
- module Probes
3
- module Mongoid
4
- class Probe
5
-
6
- def install
7
- require 'mongoid/version'
8
- version = Gem::Version.new(::Mongoid::VERSION)
9
-
10
- if version < Gem::Version.new("5.0")
11
- Skylight.probe(:moped)
12
- else
13
- Skylight.probe(:mongo)
14
- end
15
- end
16
- end
17
- end
18
-
19
- register(:mongoid, "Mongoid", "mongoid", Mongoid::Probe.new)
20
- end
21
- end
@@ -1,39 +0,0 @@
1
- module Skylight
2
- module Probes
3
- module Moped
4
- class Probe
5
-
6
- def install
7
- unless defined?(::Moped::Instrumentable)
8
- # Using $stderr here isn't great, but we don't have a logger accessible
9
- $stderr.puts "[SKYLIGHT] [#{Skylight::VERSION}] The installed version of Moped doesn't " \
10
- "support instrumentation. The Moped probe will be disabled."
11
-
12
- return
13
- end
14
-
15
- ::Moped::Instrumentable.module_eval do
16
- alias instrument_without_sk instrument
17
-
18
- def instrument(*args, &block)
19
- # Mongoid sets the instrumenter to AS::N
20
- if instrumenter == ActiveSupport::Notifications
21
- asn_block = block
22
- else
23
- # If the instrumenter hasn't been changed to AS::N use both
24
- asn_block = Proc.new do
25
- ActiveSupport::Notifications.instrument(*args, &block)
26
- end
27
- end
28
-
29
- instrument_without_sk(*args, &asn_block)
30
- end
31
- end
32
- end
33
-
34
- end
35
- end
36
-
37
- register(:moped, "Moped", "moped", Moped::Probe.new)
38
- end
39
- end
@@ -1,58 +0,0 @@
1
- require 'skylight/formatters/http'
2
-
3
- module Skylight
4
- module Probes
5
- module NetHTTP
6
- # Probe for instrumenting Net::HTTP requests. Works by monkeypatching the default Net::HTTP#request method.
7
- class Probe
8
- DISABLED_KEY = :__skylight_net_http_disabled
9
-
10
- def self.disable
11
- Thread.current[DISABLED_KEY] = true
12
- yield
13
- ensure
14
- Thread.current[DISABLED_KEY] = false
15
- end
16
-
17
- def self.disabled?
18
- !!Thread.current[DISABLED_KEY]
19
- end
20
-
21
- def install
22
- Net::HTTP.class_eval do
23
- alias request_without_sk request
24
-
25
- def request(req, body = nil, &block)
26
- if !started? || Skylight::Probes::NetHTTP::Probe.disabled?
27
- return request_without_sk(req, body, &block)
28
- end
29
-
30
- method = req.method
31
-
32
- # req['host'] also includes special handling for default ports
33
- host, port = req['host'] ? req['host'].split(':') : nil
34
-
35
- # If we're connected with a persistent socket
36
- host ||= self.address
37
- port ||= self.port
38
-
39
- path = req.path
40
- scheme = use_ssl? ? "https" : "http"
41
-
42
- # Contained in the path
43
- query = nil
44
-
45
- opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
46
-
47
- Skylight.instrument(opts) do
48
- request_without_sk(req, body, &block)
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
55
-
56
- register(:net_http, "Net::HTTP", "net/http", NetHTTP::Probe.new)
57
- end
58
- end
@@ -1,71 +0,0 @@
1
- module Skylight
2
- module Probes
3
- module Redis
4
- class Probe
5
- def install
6
- version = defined?(::Redis::VERSION) ? Gem::Version.new(::Redis::VERSION) : nil
7
-
8
- if !version || version < Gem::Version.new("3.0.0")
9
- # Using $stderr here isn't great, but we don't have a logger accessible
10
- $stderr.puts "[SKYLIGHT] [#{Skylight::VERSION}] The installed version of Redis doesn't " \
11
- "support Middlewares. At least version 3.0.0 is required."
12
- return
13
- end
14
-
15
- ::Redis::Client.class_eval do
16
- alias call_without_sk call
17
-
18
- def call(command, &block)
19
- command_name = command[0]
20
-
21
- return call_without_sk(command, &block) if command_name == :auth
22
-
23
- opts = {
24
- category: "db.redis.command",
25
- title: command_name.upcase.to_s
26
- }
27
-
28
- Skylight.instrument(opts) do
29
- call_without_sk(command, &block)
30
- end
31
- end
32
- end
33
- end
34
-
35
- # Unfortunately, because of the nature of pipelining, there's no way for us to
36
- # give a time breakdown on the individual items.
37
-
38
- PIPELINED_OPTS = {
39
- category: "db.redis.pipelined".freeze,
40
- title: "PIPELINE".freeze
41
- }.freeze
42
-
43
- MULTI_OPTS = {
44
- category: "db.redis.multi".freeze,
45
- title: "MULTI".freeze
46
- }.freeze
47
-
48
- ::Redis.class_eval do
49
- alias pipelined_without_sk pipelined
50
-
51
- def pipelined(&block)
52
- Skylight.instrument(PIPELINED_OPTS) do
53
- pipelined_without_sk(&block)
54
- end
55
- end
56
-
57
-
58
- alias multi_without_sk multi
59
-
60
- def multi(&block)
61
- Skylight.instrument(MULTI_OPTS) do
62
- multi_without_sk(&block)
63
- end
64
- end
65
- end
66
- end
67
- end
68
-
69
- register(:redis, "Redis", "redis", Redis::Probe.new)
70
- end
71
- end
@@ -1,37 +0,0 @@
1
- # Supports 3.12.0+
2
- module Skylight
3
- module Probes
4
- module Sequel
5
- class Probe
6
- def install
7
- if Gem::Version.new(::Sequel.version) < Gem::Version.new('4.0')
8
- Skylight::DEPRECATOR.deprecation_warning("Support for Sequel versions before 4.0")
9
- end
10
-
11
- require 'sequel/database/logging'
12
-
13
- method_name = ::Sequel::Database.method_defined?(:log_connection_yield) ? 'log_connection_yield' : 'log_yield'
14
-
15
- ::Sequel::Database.class_eval <<-end_eval
16
- alias #{method_name}_without_sk #{method_name}
17
-
18
- def #{method_name}(sql, *args, &block)
19
- #{method_name}_without_sk(sql, *args) do
20
- ::ActiveSupport::Notifications.instrument(
21
- "sql.sequel",
22
- sql: sql,
23
- name: "SQL",
24
- binds: args
25
- ) do
26
- block.call
27
- end
28
- end
29
- end
30
- end_eval
31
- end
32
- end
33
- end
34
-
35
- register(:sequel, "Sequel", "sequel", Sequel::Probe.new)
36
- end
37
- end