skylight 4.2.3 → 5.3.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 +4 -4
- data/CHANGELOG.md +420 -331
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +2 -8
- data/ERRORS.md +3 -0
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +61 -56
- data/ext/libskylight.yml +8 -6
- data/ext/skylight_native.c +26 -100
- data/lib/skylight/api.rb +32 -21
- data/lib/skylight/cli/doctor.rb +64 -65
- data/lib/skylight/cli/helpers.rb +19 -19
- data/lib/skylight/cli/merger.rb +142 -138
- data/lib/skylight/cli.rb +48 -46
- data/lib/skylight/config.rb +640 -201
- data/lib/skylight/data/cacert.pem +730 -1023
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +26 -9
- data/lib/skylight/extensions/source_location.rb +291 -0
- data/lib/skylight/extensions.rb +95 -0
- data/lib/skylight/formatters/http.rb +18 -0
- data/lib/skylight/gc.rb +99 -0
- data/lib/skylight/helpers.rb +81 -36
- data/lib/skylight/instrumenter.rb +336 -18
- data/lib/skylight/middleware.rb +147 -1
- data/lib/skylight/native.rb +60 -12
- data/lib/skylight/native_ext_fetcher.rb +13 -14
- data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
- data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
- data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
- data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
- data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
- data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
- data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
- data/lib/skylight/normalizers/active_job/perform.rb +87 -0
- data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
- data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
- data/lib/skylight/normalizers/active_record/sql.rb +20 -0
- data/lib/skylight/normalizers/active_storage.rb +28 -0
- data/lib/skylight/normalizers/active_support/cache.rb +11 -0
- data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
- data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
- data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
- data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
- data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
- data/lib/skylight/normalizers/default.rb +24 -0
- data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
- data/lib/skylight/normalizers/faraday/request.rb +38 -0
- data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
- data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
- data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
- data/lib/skylight/normalizers/grape/format_response.rb +20 -0
- data/lib/skylight/normalizers/graphiti/render.rb +22 -0
- data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
- data/lib/skylight/normalizers/graphql/base.rb +127 -0
- data/lib/skylight/normalizers/render.rb +79 -0
- data/lib/skylight/normalizers/sequel/sql.rb +12 -0
- data/lib/skylight/normalizers/shrine.rb +32 -0
- data/lib/skylight/normalizers/sql.rb +41 -0
- data/lib/skylight/normalizers.rb +157 -0
- data/lib/skylight/probes/action_controller.rb +52 -0
- data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
- data/lib/skylight/probes/action_dispatch.rb +2 -0
- data/lib/skylight/probes/action_view.rb +42 -0
- data/lib/skylight/probes/active_job.rb +27 -0
- data/lib/skylight/probes/active_job_enqueue.rb +35 -0
- data/lib/skylight/probes/active_model_serializers.rb +50 -0
- data/lib/skylight/probes/active_record_async.rb +96 -0
- data/lib/skylight/probes/delayed_job.rb +144 -0
- data/lib/skylight/probes/elasticsearch.rb +36 -0
- data/lib/skylight/probes/excon/middleware.rb +65 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/faraday.rb +23 -0
- data/lib/skylight/probes/graphql.rb +38 -0
- data/lib/skylight/probes/httpclient.rb +44 -0
- data/lib/skylight/probes/middleware.rb +135 -0
- data/lib/skylight/probes/mongo.rb +156 -0
- data/lib/skylight/probes/mongoid.rb +13 -0
- data/lib/skylight/probes/net_http.rb +54 -0
- data/lib/skylight/probes/rack_builder.rb +37 -0
- data/lib/skylight/probes/redis.rb +51 -0
- data/lib/skylight/probes/sequel.rb +29 -0
- data/lib/skylight/probes/sinatra.rb +66 -0
- data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
- data/lib/skylight/probes/tilt.rb +25 -0
- data/lib/skylight/probes.rb +173 -0
- data/lib/skylight/railtie.rb +166 -28
- data/lib/skylight/sidekiq.rb +47 -0
- data/lib/skylight/sinatra.rb +1 -1
- data/lib/skylight/subscriber.rb +130 -0
- data/lib/skylight/test.rb +147 -0
- data/lib/skylight/trace.rb +325 -22
- data/lib/skylight/user_config.rb +58 -0
- data/lib/skylight/util/allocation_free.rb +26 -0
- data/lib/skylight/util/clock.rb +57 -0
- data/lib/skylight/util/component.rb +22 -22
- data/lib/skylight/util/deploy.rb +19 -24
- data/lib/skylight/util/gzip.rb +20 -0
- data/lib/skylight/util/http.rb +106 -113
- data/lib/skylight/util/instrumenter_method.rb +26 -0
- data/lib/skylight/util/logging.rb +136 -0
- data/lib/skylight/util/lru_cache.rb +36 -0
- data/lib/skylight/util/platform.rb +3 -7
- data/lib/skylight/util/ssl.rb +1 -25
- data/lib/skylight/util.rb +12 -0
- data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
- data/lib/skylight/version.rb +5 -1
- data/lib/skylight/vm/gc.rb +60 -0
- data/lib/skylight.rb +201 -14
- metadata +134 -18
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "zlib"
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Util
|
|
5
|
+
# Provides Gzip compressing support
|
|
6
|
+
module Gzip
|
|
7
|
+
# Compress a string with Gzip
|
|
8
|
+
#
|
|
9
|
+
# @param str [String] uncompressed string
|
|
10
|
+
# @return [String] compressed string
|
|
11
|
+
def self.compress(str)
|
|
12
|
+
output = StringIO.new
|
|
13
|
+
gz = Zlib::GzipWriter.new(output)
|
|
14
|
+
gz.write(str)
|
|
15
|
+
gz.close
|
|
16
|
+
output.string
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/skylight/util/http.rb
CHANGED
|
@@ -3,23 +3,23 @@ require "json"
|
|
|
3
3
|
require "openssl"
|
|
4
4
|
require "net/http"
|
|
5
5
|
require "net/https"
|
|
6
|
-
require "skylight/
|
|
6
|
+
require "skylight/util/gzip"
|
|
7
7
|
require "skylight/util/ssl"
|
|
8
8
|
|
|
9
9
|
module Skylight
|
|
10
10
|
module Util
|
|
11
11
|
class HTTP
|
|
12
12
|
CONTENT_ENCODING = "content-encoding".freeze
|
|
13
|
-
CONTENT_LENGTH
|
|
14
|
-
CONTENT_TYPE
|
|
15
|
-
ACCEPT
|
|
16
|
-
X_VERSION_HDR
|
|
13
|
+
CONTENT_LENGTH = "content-length".freeze
|
|
14
|
+
CONTENT_TYPE = "content-type".freeze
|
|
15
|
+
ACCEPT = "Accept".freeze
|
|
16
|
+
X_VERSION_HDR = "x-skylight-agent-version".freeze
|
|
17
17
|
APPLICATION_JSON = "application/json".freeze
|
|
18
|
-
AUTHORIZATION
|
|
19
|
-
DEFLATE
|
|
20
|
-
GZIP
|
|
18
|
+
AUTHORIZATION = "authorization".freeze
|
|
19
|
+
DEFLATE = "deflate".freeze
|
|
20
|
+
GZIP = "gzip".freeze
|
|
21
21
|
|
|
22
|
-
include
|
|
22
|
+
include Logging
|
|
23
23
|
|
|
24
24
|
attr_accessor :authentication
|
|
25
25
|
attr_reader :host, :port, :config
|
|
@@ -35,7 +35,8 @@ module Skylight
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
class ReadResponseError < StandardError
|
|
38
|
+
class ReadResponseError < StandardError
|
|
39
|
+
end
|
|
39
40
|
|
|
40
41
|
def initialize(config, service = :auth, opts = {})
|
|
41
42
|
@config = config
|
|
@@ -46,7 +47,7 @@ module Skylight
|
|
|
46
47
|
|
|
47
48
|
url = URI.parse(url)
|
|
48
49
|
|
|
49
|
-
@ssl
|
|
50
|
+
@ssl = url.scheme == "https"
|
|
50
51
|
@host = url.host
|
|
51
52
|
@port = url.port
|
|
52
53
|
|
|
@@ -81,137 +82,129 @@ module Skylight
|
|
|
81
82
|
|
|
82
83
|
private
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
85
|
+
def get_timeout(type, config, service, opts)
|
|
86
|
+
config.duration_ms("#{service}_http_#{type}_timeout") || opts[:timeout] || 15
|
|
87
|
+
end
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
def build_request(type, endpoint, hdrs, length = nil)
|
|
90
|
+
headers = {}
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
headers[CONTENT_LENGTH] = length.to_s if length
|
|
93
|
+
headers[AUTHORIZATION] = authentication if authentication
|
|
94
|
+
headers[ACCEPT] = APPLICATION_JSON
|
|
95
|
+
headers[X_VERSION_HDR] = VERSION
|
|
96
|
+
headers[CONTENT_ENCODING] = GZIP if length && @deflate
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
headers[k] = v
|
|
100
|
-
end
|
|
98
|
+
hdrs.each { |k, v| headers[k] = v }
|
|
101
99
|
|
|
102
|
-
|
|
100
|
+
type.new(endpoint, headers)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def do_request(http, req)
|
|
104
|
+
begin
|
|
105
|
+
client = http.start
|
|
106
|
+
rescue StandardError => e
|
|
107
|
+
# TODO: Retry here
|
|
108
|
+
raise StartError, e
|
|
103
109
|
end
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
raise StartError, e
|
|
111
|
-
end
|
|
111
|
+
begin
|
|
112
|
+
res = client.request(req)
|
|
113
|
+
rescue *READ_EXCEPTIONS => e
|
|
114
|
+
raise ReadResponseError, e.inspect
|
|
115
|
+
end
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
end
|
|
117
|
+
yield res
|
|
118
|
+
ensure
|
|
119
|
+
client&.finish
|
|
120
|
+
end
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
def execute(req, body = nil)
|
|
123
|
+
t do
|
|
124
|
+
fmt "executing HTTP request; host=%s; port=%s; path=%s, body=%s",
|
|
125
|
+
@host,
|
|
126
|
+
@port,
|
|
127
|
+
req.path,
|
|
128
|
+
body && body.bytesize
|
|
122
129
|
end
|
|
123
130
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
end
|
|
131
|
+
if body
|
|
132
|
+
body = Gzip.compress(body) if @deflate
|
|
133
|
+
req.body = body
|
|
134
|
+
end
|
|
129
135
|
|
|
130
|
-
|
|
131
|
-
body = Gzip.compress(body) if @deflate
|
|
132
|
-
req.body = body
|
|
133
|
-
end
|
|
136
|
+
http = Net::HTTP.new(@host, @port, @proxy_addr, @proxy_port, @proxy_user, @proxy_pass)
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
http.open_timeout = @open_timeout
|
|
139
|
+
http.read_timeout = @read_timeout
|
|
137
140
|
|
|
138
|
-
|
|
139
|
-
http.
|
|
141
|
+
if @ssl
|
|
142
|
+
http.use_ssl = true
|
|
140
143
|
|
|
141
|
-
|
|
142
|
-
http.use_ssl = true
|
|
144
|
+
http.ca_file = SSL.ca_cert_file_or_default unless SSL.ca_cert_file?
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
end
|
|
146
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
147
|
+
end
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
do_request(http, req) do |res|
|
|
150
|
+
unless res.code =~ /2\d\d/
|
|
151
|
+
debug "server responded with #{res.code}"
|
|
152
|
+
t { fmt "body=%s", res.body }
|
|
149
153
|
end
|
|
150
154
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
Response.new(res.code.to_i, res, res.body)
|
|
156
|
+
end
|
|
157
|
+
rescue Exception => e
|
|
158
|
+
error "http %s %s failed; error=%s; msg=%s", req.method, req.path, e.class, e.message
|
|
159
|
+
t { e.backtrace.join("\n") }
|
|
160
|
+
ErrorResponse.new(req, e)
|
|
161
|
+
end
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
rescue Exception => e
|
|
160
|
-
error "http %s %s failed; error=%s; msg=%s", req.method, req.path, e.class, e.message
|
|
161
|
-
t { e.backtrace.join("\n") }
|
|
162
|
-
ErrorResponse.new(req, e)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
class Response
|
|
166
|
-
attr_reader :status, :headers, :body, :exception
|
|
167
|
-
|
|
168
|
-
def initialize(status, headers, body)
|
|
169
|
-
@status = status
|
|
170
|
-
@headers = headers
|
|
171
|
-
|
|
172
|
-
if (headers[CONTENT_TYPE] || "").include?(APPLICATION_JSON)
|
|
173
|
-
begin
|
|
174
|
-
@body = JSON.parse(body)
|
|
175
|
-
rescue JSON::ParserError
|
|
176
|
-
@body = body # not really JSON I guess
|
|
177
|
-
end
|
|
178
|
-
else
|
|
179
|
-
@body = body
|
|
180
|
-
end
|
|
181
|
-
end
|
|
163
|
+
class Response
|
|
164
|
+
attr_reader :status, :headers, :body, :exception
|
|
182
165
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
166
|
+
def initialize(status, headers, body)
|
|
167
|
+
@status = status
|
|
168
|
+
@headers = headers
|
|
186
169
|
|
|
187
|
-
|
|
188
|
-
|
|
170
|
+
if (headers[CONTENT_TYPE] || "").include?(APPLICATION_JSON)
|
|
171
|
+
begin
|
|
172
|
+
@body = JSON.parse(body)
|
|
173
|
+
rescue JSON::ParserError
|
|
174
|
+
@body = body # not really JSON I guess
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
@body = body
|
|
189
178
|
end
|
|
179
|
+
end
|
|
190
180
|
|
|
191
|
-
|
|
192
|
-
|
|
181
|
+
def success?
|
|
182
|
+
status >= 200 && status < 300
|
|
183
|
+
end
|
|
193
184
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
end
|
|
198
|
-
res
|
|
199
|
-
end
|
|
185
|
+
def to_s
|
|
186
|
+
body.to_s
|
|
187
|
+
end
|
|
200
188
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
189
|
+
def get(key)
|
|
190
|
+
body.dig(*key.split(".")) if body.is_a?(Hash)
|
|
191
|
+
end
|
|
204
192
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
193
|
+
def respond_to_missing?(name, include_all = false)
|
|
194
|
+
super || body.respond_to?(name, include_all)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def method_missing(name, *args, &blk)
|
|
198
|
+
if respond_to_missing?(name)
|
|
199
|
+
body.send(name, *args, &blk)
|
|
200
|
+
else
|
|
201
|
+
super
|
|
211
202
|
end
|
|
212
203
|
end
|
|
204
|
+
end
|
|
213
205
|
|
|
214
|
-
|
|
206
|
+
ErrorResponse =
|
|
207
|
+
Struct.new(:request, :exception) do
|
|
215
208
|
def status
|
|
216
209
|
nil
|
|
217
210
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Util
|
|
3
|
+
module InstrumenterMethod
|
|
4
|
+
def instrumenter_method(name, block: false)
|
|
5
|
+
if block
|
|
6
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
7
|
+
def #{name}(*args) # def mute(*args)
|
|
8
|
+
unless instrumenter # unless instrumenter
|
|
9
|
+
return yield if block_given? # return yield if block_given?
|
|
10
|
+
return # return
|
|
11
|
+
end # end
|
|
12
|
+
#
|
|
13
|
+
instrumenter.#{name}(*args) { yield } # instrumenter.mute(*args) { yield }
|
|
14
|
+
end # end
|
|
15
|
+
RUBY
|
|
16
|
+
else
|
|
17
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
18
|
+
def #{name}(*args) # def config(*args)
|
|
19
|
+
instrumenter&.#{name}(*args) # instrumenter&.config(*args)
|
|
20
|
+
end # end
|
|
21
|
+
RUBY
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require "logger"
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Util
|
|
5
|
+
# Log both to the specified logger and STDOUT
|
|
6
|
+
class AlertLogger
|
|
7
|
+
def initialize(logger)
|
|
8
|
+
@logger = logger
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def write(*args)
|
|
12
|
+
$stderr.write(*args)
|
|
13
|
+
|
|
14
|
+
# Try to avoid writing to STDOUT/STDERR twice
|
|
15
|
+
logger_logdev = @logger.instance_variable_get(:@logdev)
|
|
16
|
+
logger_out = logger_logdev.respond_to?(:dev) ? logger_logdev.dev : nil
|
|
17
|
+
@logger.<<(*args) if logger_out != $stdout && logger_out != $stderr
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def close; end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
module Logging
|
|
24
|
+
def log_context
|
|
25
|
+
{}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def trace?
|
|
29
|
+
!!ENV[-"SKYLIGHT_ENABLE_TRACE_LOGS"]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def raise_on_error?
|
|
33
|
+
!!ENV[-"SKYLIGHT_RAISE_ON_ERROR"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Logs if tracing
|
|
37
|
+
#
|
|
38
|
+
# @param (see #debug)
|
|
39
|
+
#
|
|
40
|
+
# See {trace?}.
|
|
41
|
+
def trace(msg, *args)
|
|
42
|
+
return unless trace?
|
|
43
|
+
|
|
44
|
+
log :debug, msg, *args
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Evaluates and logs the result of the block if tracing
|
|
48
|
+
#
|
|
49
|
+
# @yield block to be evaluted
|
|
50
|
+
# @yieldreturn arguments for {#debug}
|
|
51
|
+
#
|
|
52
|
+
# See {trace?}.
|
|
53
|
+
def t
|
|
54
|
+
return unless trace?
|
|
55
|
+
|
|
56
|
+
log :debug, yield
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param msg (see #log)
|
|
60
|
+
# @param args (see #log)
|
|
61
|
+
def debug(msg, *args)
|
|
62
|
+
log :debug, msg, *args
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @param msg (see #log)
|
|
66
|
+
# @param args (see #log)
|
|
67
|
+
def info(msg, *args)
|
|
68
|
+
log :info, msg, *args
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @param msg (see #log)
|
|
72
|
+
# @param args (see #log)
|
|
73
|
+
def warn(msg, *args)
|
|
74
|
+
log :warn, msg, *args
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param msg (see #log)
|
|
78
|
+
# @param args (see #log)
|
|
79
|
+
def error(msg, *args)
|
|
80
|
+
log :error, msg, *args
|
|
81
|
+
raise format(msg, *args) if raise_on_error?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias log_trace trace
|
|
85
|
+
alias log_debug debug
|
|
86
|
+
alias log_info info
|
|
87
|
+
alias log_warn warn
|
|
88
|
+
alias log_error error
|
|
89
|
+
|
|
90
|
+
# Alias for `Kernel#sprintf`
|
|
91
|
+
# @return [String]
|
|
92
|
+
def fmt(*args)
|
|
93
|
+
sprintf(*args)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def config_for_logging
|
|
97
|
+
if respond_to?(:config)
|
|
98
|
+
config
|
|
99
|
+
elsif is_a?(Skylight::Config)
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @param level [String,Symbol] the method on `logger` to use for logging
|
|
105
|
+
# @param msg [String] the message to log
|
|
106
|
+
# @param args [Array] values for `Kernel#sprintf` on `msg`
|
|
107
|
+
def log(level, msg, *args)
|
|
108
|
+
c = config_for_logging
|
|
109
|
+
logger = c ? c.logger : nil
|
|
110
|
+
|
|
111
|
+
msg = log_context.map { |(k, v)| "#{k}=#{v}; " }.join << msg
|
|
112
|
+
|
|
113
|
+
if logger
|
|
114
|
+
if logger.respond_to?(level)
|
|
115
|
+
if args.empty?
|
|
116
|
+
logger.send level, msg
|
|
117
|
+
else
|
|
118
|
+
logger.send level, format(msg, *args)
|
|
119
|
+
end
|
|
120
|
+
return # rubocop:disable Style/RedundantReturn
|
|
121
|
+
else
|
|
122
|
+
Kernel.warn "Invalid logger"
|
|
123
|
+
end
|
|
124
|
+
# Fallback to stderr for warn and error levels
|
|
125
|
+
elsif %i[warn error].include?(level)
|
|
126
|
+
$stderr.puts format("[SKYLIGHT] #{msg}", *args)
|
|
127
|
+
end
|
|
128
|
+
rescue Exception => e
|
|
129
|
+
if trace?
|
|
130
|
+
puts "[ERROR] #{e.message}"
|
|
131
|
+
puts e.backtrace
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Based on code by Sam Saffron: https://stackoverflow.com/a/16161783/181916
|
|
2
|
+
module Skylight
|
|
3
|
+
module Util
|
|
4
|
+
class LruCache
|
|
5
|
+
def initialize(max_size)
|
|
6
|
+
@max_size = max_size
|
|
7
|
+
@data = {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def max_size=(size)
|
|
11
|
+
raise ArgumentError, :max_size if @max_size < 1
|
|
12
|
+
|
|
13
|
+
@max_size = size
|
|
14
|
+
@data.shift while @data.size > @max_size
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Individual hash operations here are atomic in MRI.
|
|
18
|
+
def fetch(key)
|
|
19
|
+
found = true
|
|
20
|
+
value = @data.delete(key) { found = false }
|
|
21
|
+
|
|
22
|
+
value = yield if !found && block_given?
|
|
23
|
+
|
|
24
|
+
@data[key] = value if value
|
|
25
|
+
|
|
26
|
+
@data.shift if !found && value && @data.length > @max_size
|
|
27
|
+
|
|
28
|
+
value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def clear
|
|
32
|
+
@data.clear
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -12,11 +12,7 @@ module Skylight
|
|
|
12
12
|
# Ruby doesn't know that it's on a musl-based platform. `ldd` is the
|
|
13
13
|
# only reliable way to detect musl that we've found.
|
|
14
14
|
# See https://github.com/skylightio/skylight-ruby/issues/92
|
|
15
|
-
|
|
16
|
-
"linux-musl"
|
|
17
|
-
else
|
|
18
|
-
"linux"
|
|
19
|
-
end
|
|
15
|
+
ENV["SKYLIGHT_MUSL"] || `ldd --version 2>&1` =~ /musl/ ? "linux-musl" : "linux"
|
|
20
16
|
when /darwin/
|
|
21
17
|
"darwin"
|
|
22
18
|
when /freebsd/
|
|
@@ -42,8 +38,8 @@ module Skylight
|
|
|
42
38
|
"x86"
|
|
43
39
|
when /ppc|powerpc/
|
|
44
40
|
"powerpc"
|
|
45
|
-
when
|
|
46
|
-
"
|
|
41
|
+
when /arm64|aarch64/
|
|
42
|
+
"aarch64"
|
|
47
43
|
else
|
|
48
44
|
cpu
|
|
49
45
|
end
|
data/lib/skylight/util/ssl.rb
CHANGED
|
@@ -12,43 +12,19 @@ module Skylight
|
|
|
12
12
|
if defined?(OpenSSL::X509::DEFAULT_CERT_FILE)
|
|
13
13
|
f = OpenSSL::X509::DEFAULT_CERT_FILE
|
|
14
14
|
|
|
15
|
-
if f && File.exist?(f)
|
|
16
|
-
@ca_cert_file = f
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self.detect_ca_cert_dir!
|
|
22
|
-
return nil if ENV["SKYLIGHT_FORCE_OWN_CERTS"]
|
|
23
|
-
|
|
24
|
-
@ca_cert_dir = false
|
|
25
|
-
if defined?(OpenSSL::X509::DEFAULT_CERT_DIR)
|
|
26
|
-
d = OpenSSL::X509::DEFAULT_CERT_DIR
|
|
27
|
-
|
|
28
|
-
if d && File.exist?(d)
|
|
29
|
-
@ca_cert_dir = d
|
|
30
|
-
end
|
|
15
|
+
@ca_cert_file = f if f && File.exist?(f)
|
|
31
16
|
end
|
|
32
17
|
end
|
|
33
18
|
|
|
34
19
|
detect_ca_cert_file!
|
|
35
|
-
detect_ca_cert_dir!
|
|
36
20
|
|
|
37
21
|
def self.ca_cert_file?
|
|
38
22
|
!!@ca_cert_file
|
|
39
23
|
end
|
|
40
24
|
|
|
41
|
-
def self.ca_cert_dir?
|
|
42
|
-
!!@ca_cert_dir
|
|
43
|
-
end
|
|
44
|
-
|
|
45
25
|
def self.ca_cert_file_or_default
|
|
46
26
|
@ca_cert_file || DEFAULT_CA_FILE
|
|
47
27
|
end
|
|
48
|
-
|
|
49
|
-
class << self
|
|
50
|
-
attr_reader :ca_cert_dir
|
|
51
|
-
end
|
|
52
28
|
end
|
|
53
29
|
end
|
|
54
30
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
# @api private
|
|
3
|
+
module Util
|
|
4
|
+
# Used from the main lib
|
|
5
|
+
require "skylight/util/allocation_free"
|
|
6
|
+
require "skylight/util/clock"
|
|
7
|
+
require "skylight/util/instrumenter_method"
|
|
8
|
+
|
|
9
|
+
# Used from the CLI
|
|
10
|
+
autoload :Gzip, "skylight/util/gzip"
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/skylight/version.rb
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
module Skylight
|
|
2
|
-
|
|
2
|
+
# pre-release versions should be given here as "5.0.0-alpha"
|
|
3
|
+
# for compatibility with semver when it is parsed by the rust agent.
|
|
4
|
+
# This string will be transformed in the gemspec to "5.0.0.alpha"
|
|
5
|
+
# to conform with rubygems.
|
|
6
|
+
VERSION = "5.3.0".freeze
|
|
3
7
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
# @api private
|
|
3
|
+
module VM
|
|
4
|
+
if defined?(JRUBY_VERSION)
|
|
5
|
+
# This doesn't quite work as we would like it. I believe that the GC
|
|
6
|
+
# statistics includes time that is not stop-the-world, this does not
|
|
7
|
+
# necessarily take time away from the application.
|
|
8
|
+
#
|
|
9
|
+
# require 'java'
|
|
10
|
+
# class GC
|
|
11
|
+
# def initialize
|
|
12
|
+
# @factory = Java::JavaLangManagement::ManagementFactory
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# def enable
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# def total_time
|
|
19
|
+
# res = 0.0
|
|
20
|
+
#
|
|
21
|
+
# @factory.garbage_collector_mx_beans.each do |mx|
|
|
22
|
+
# res += (mx.collection_time.to_f / 1_000.0)
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# res
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
elsif defined?(::GC::Profiler)
|
|
29
|
+
class GC
|
|
30
|
+
def initialize
|
|
31
|
+
@total = 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def enable
|
|
35
|
+
::GC::Profiler.enable
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def total_time
|
|
39
|
+
# Reported in seconds
|
|
40
|
+
run = (::GC::Profiler.total_time * 1_000_000).to_i
|
|
41
|
+
|
|
42
|
+
::GC::Profiler.clear if run > 0
|
|
43
|
+
|
|
44
|
+
@total += run
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Fallback
|
|
50
|
+
unless defined?(VM::GC)
|
|
51
|
+
class GC
|
|
52
|
+
def enable; end
|
|
53
|
+
|
|
54
|
+
def total_time
|
|
55
|
+
0
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|