skylight 3.1.4 → 5.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +465 -294
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +11 -3
- data/ERRORS.md +3 -0
- data/LICENSE.md +8 -18
- data/README.md +1 -2
- data/bin/skylight +1 -1
- data/ext/extconf.rb +118 -122
- data/ext/libskylight.yml +8 -6
- data/ext/skylight_native.c +56 -100
- data/lib/skylight/api.rb +41 -27
- data/lib/skylight/cli/doctor.rb +68 -70
- data/lib/skylight/cli/helpers.rb +3 -5
- data/lib/skylight/cli/merger.rb +99 -92
- data/lib/skylight/cli.rb +40 -43
- data/lib/skylight/config.rb +656 -201
- data/lib/skylight/data/cacert.pem +730 -1023
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +34 -16
- 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 +82 -39
- data/lib/skylight/instrumenter.rb +339 -9
- data/lib/skylight/middleware.rb +147 -1
- data/lib/skylight/native.rb +71 -23
- data/lib/skylight/native_ext_fetcher.rb +39 -47
- 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 +45 -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 +169 -0
- data/lib/skylight/probes/mongoid.rb +6 -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 +68 -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 +172 -0
- data/lib/skylight/railtie.rb +172 -15
- data/lib/skylight/sidekiq.rb +47 -0
- data/lib/skylight/sinatra.rb +2 -2
- data/lib/skylight/subscriber.rb +130 -0
- data/lib/skylight/test.rb +147 -0
- data/lib/skylight/trace.rb +331 -15
- data/lib/skylight/user_config.rb +60 -0
- data/lib/skylight/util/allocation_free.rb +26 -0
- data/lib/skylight/util/clock.rb +57 -0
- data/lib/skylight/util/component.rb +47 -9
- data/lib/skylight/util/deploy.rb +24 -40
- data/lib/skylight/util/gzip.rb +20 -0
- data/lib/skylight/util/hostname.rb +4 -4
- data/lib/skylight/util/http.rb +62 -71
- 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 +74 -0
- data/lib/skylight/util/proxy.rb +13 -0
- data/lib/skylight/util/ssl.rb +4 -28
- 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 +213 -24
- metadata +171 -53
@@ -1,33 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
|
1
5
|
module Skylight
|
2
6
|
module Util
|
3
7
|
class Component
|
4
|
-
|
5
8
|
attr_accessor :environment, :name
|
6
9
|
|
7
|
-
NAME_FORMAT = /\A[a-
|
8
|
-
DEFAULT_NAME =
|
9
|
-
|
10
|
+
NAME_FORMAT = /\A[a-zA-Z0-9_-]+\z/.freeze
|
11
|
+
DEFAULT_NAME = "web"
|
12
|
+
WORKER_NAME = "worker"
|
13
|
+
DEFAULT_ENVIRONMENT = "production"
|
10
14
|
|
11
|
-
def initialize(environment, name)
|
15
|
+
def initialize(environment, name, force_worker: false)
|
12
16
|
@environment = environment || DEFAULT_ENVIRONMENT
|
13
|
-
@name
|
17
|
+
@name = resolve_name(name, force_worker)
|
14
18
|
|
15
19
|
raise ArgumentError, "environment can't be blank" if @environment.empty?
|
16
|
-
|
17
|
-
validate_string!(@
|
20
|
+
|
21
|
+
validate_string!(@environment, "environment")
|
22
|
+
validate_string!(@name, "name")
|
18
23
|
end
|
19
24
|
|
20
25
|
def to_s
|
21
26
|
"#{name}:#{environment}"
|
22
27
|
end
|
23
28
|
|
29
|
+
def to_encoded_s
|
30
|
+
@to_encoded_s ||= URI.encode_www_form_component(to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
def web?
|
34
|
+
name == DEFAULT_NAME
|
35
|
+
end
|
36
|
+
|
37
|
+
def worker?
|
38
|
+
!web?
|
39
|
+
end
|
40
|
+
|
41
|
+
# keys here should match those from the main config
|
42
|
+
def as_json(*)
|
43
|
+
{ component: name, env: environment }
|
44
|
+
end
|
45
|
+
|
24
46
|
private
|
25
47
|
|
48
|
+
def program_name
|
49
|
+
$PROGRAM_NAME
|
50
|
+
end
|
51
|
+
|
52
|
+
def argv
|
53
|
+
ARGV
|
54
|
+
end
|
55
|
+
|
56
|
+
def resolve_name(given_name, force_worker)
|
57
|
+
# don't allow workers to be called 'web'
|
58
|
+
return WORKER_NAME if force_worker && (given_name.nil? || given_name == DEFAULT_NAME)
|
59
|
+
return DEFAULT_NAME if given_name.nil?
|
60
|
+
|
61
|
+
given_name
|
62
|
+
end
|
63
|
+
|
26
64
|
def validate_string!(string, kind)
|
27
65
|
return true if string =~ NAME_FORMAT
|
66
|
+
|
28
67
|
raise ArgumentError, "#{kind} can only contain lowercase letters, numbers, and dashes"
|
29
68
|
end
|
30
69
|
end
|
31
70
|
end
|
32
71
|
end
|
33
|
-
|
data/lib/skylight/util/deploy.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "json"
|
2
|
+
require "skylight/util/logging"
|
3
3
|
|
4
4
|
module Skylight
|
5
5
|
module Util
|
6
|
-
|
7
6
|
module Deploy
|
8
|
-
|
9
7
|
def self.build(config)
|
10
8
|
DEPLOY_TYPES.each do |type|
|
11
9
|
deploy = type.new(config)
|
@@ -15,9 +13,7 @@ module Skylight
|
|
15
13
|
end
|
16
14
|
|
17
15
|
class EmptyDeploy
|
18
|
-
|
19
|
-
attr_reader :config
|
20
|
-
attr_reader :timestamp
|
16
|
+
attr_reader :config, :timestamp
|
21
17
|
|
22
18
|
def initialize(config)
|
23
19
|
@config = config
|
@@ -38,75 +34,66 @@ module Skylight
|
|
38
34
|
|
39
35
|
def to_query_hash
|
40
36
|
hash = {
|
41
|
-
timestamp:
|
42
|
-
deploy_id:
|
37
|
+
timestamp: timestamp,
|
38
|
+
deploy_id: id.to_s[0..100] # Keep this sane
|
43
39
|
}
|
44
40
|
hash[:git_sha] = git_sha.to_s[0..40] if git_sha # A valid SHA will never exceed 40
|
45
41
|
hash[:description] = description[0..255] if description # Avoid massive descriptions
|
46
42
|
hash
|
47
43
|
end
|
48
|
-
|
49
44
|
end
|
50
45
|
|
51
46
|
class DefaultDeploy < EmptyDeploy
|
52
|
-
include
|
47
|
+
include Util::Logging
|
53
48
|
|
54
49
|
def initialize(*)
|
55
50
|
super
|
56
|
-
if description && !id
|
57
|
-
warn "The configured deploy will be ignored as an id or git_sha must be provided."
|
58
|
-
end
|
51
|
+
warn "The configured deploy will be ignored as an id or git_sha must be provided." if description && !id
|
59
52
|
end
|
60
53
|
|
61
54
|
def id
|
62
|
-
config.get(:
|
55
|
+
config.get(:"deploy.id") || git_sha
|
63
56
|
end
|
64
57
|
|
65
58
|
def git_sha
|
66
|
-
config.get(:
|
59
|
+
config.get(:"deploy.git_sha")
|
67
60
|
end
|
68
61
|
|
69
62
|
def description
|
70
|
-
config.get(:
|
63
|
+
config.get(:"deploy.description")
|
71
64
|
end
|
72
|
-
|
73
65
|
end
|
74
66
|
|
75
67
|
class HerokuDeploy < EmptyDeploy
|
76
|
-
|
77
68
|
def initialize(*)
|
78
69
|
super
|
79
70
|
@info = get_info
|
80
71
|
end
|
81
72
|
|
82
73
|
def id
|
83
|
-
@info ? @info[
|
74
|
+
@info ? @info["id"] : nil
|
84
75
|
end
|
85
76
|
|
86
77
|
def git_sha
|
87
|
-
@info ? @info[
|
78
|
+
@info ? @info["commit"] : nil
|
88
79
|
end
|
89
80
|
|
90
81
|
def description
|
91
|
-
@info ? @info[
|
82
|
+
@info ? @info["description"] : nil
|
92
83
|
end
|
93
84
|
|
94
85
|
private
|
95
86
|
|
96
|
-
|
97
|
-
|
87
|
+
def get_info
|
88
|
+
info_path = config[:"heroku.dyno_info_path"]
|
98
89
|
|
99
|
-
|
100
|
-
|
101
|
-
info['release']
|
102
|
-
end
|
103
|
-
end
|
90
|
+
if File.exist?(info_path) && (info = JSON.parse(File.read(info_path)))
|
91
|
+
info["release"]
|
104
92
|
end
|
105
|
-
|
93
|
+
end
|
106
94
|
end
|
107
95
|
|
108
96
|
class GitDeploy < EmptyDeploy
|
109
|
-
|
110
97
|
attr_reader :git_sha, :description
|
111
98
|
|
112
99
|
def initialize(*)
|
@@ -116,18 +103,15 @@ module Skylight
|
|
116
103
|
|
117
104
|
private
|
118
105
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
106
|
+
def get_info
|
107
|
+
Dir.chdir(config.root) do
|
108
|
+
info = `git log -1 --pretty="%H %s" 2>&1`
|
109
|
+
info.split(" ", 2).map(&:strip) if $CHILD_STATUS.success?
|
124
110
|
end
|
125
|
-
|
111
|
+
end
|
126
112
|
end
|
127
113
|
|
128
|
-
DEPLOY_TYPES = [DefaultDeploy, HerokuDeploy, GitDeploy]
|
129
|
-
|
114
|
+
DEPLOY_TYPES = [DefaultDeploy, HerokuDeploy, GitDeploy].freeze
|
130
115
|
end
|
131
|
-
|
132
116
|
end
|
133
117
|
end
|
@@ -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
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "socket"
|
2
|
+
require "securerandom"
|
3
3
|
|
4
4
|
module Skylight
|
5
5
|
module Util
|
6
6
|
module Hostname
|
7
7
|
def self.default_hostname
|
8
|
-
if hostname = Socket.gethostname
|
8
|
+
if (hostname = Socket.gethostname)
|
9
9
|
hostname.strip!
|
10
|
-
hostname = nil if hostname ==
|
10
|
+
hostname = nil if hostname == ""
|
11
11
|
end
|
12
12
|
|
13
13
|
hostname || "gen-#{SecureRandom.uuid}"
|
data/lib/skylight/util/http.rb
CHANGED
@@ -1,70 +1,68 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
require "uri"
|
2
|
+
require "json"
|
3
|
+
require "openssl"
|
4
|
+
require "net/http"
|
5
|
+
require "net/https"
|
6
|
+
require "skylight/util/gzip"
|
7
|
+
require "skylight/util/ssl"
|
8
8
|
|
9
9
|
module Skylight
|
10
10
|
module Util
|
11
11
|
class HTTP
|
12
|
-
CONTENT_ENCODING =
|
13
|
-
CONTENT_LENGTH
|
14
|
-
CONTENT_TYPE
|
15
|
-
ACCEPT
|
16
|
-
X_VERSION_HDR
|
17
|
-
APPLICATION_JSON =
|
18
|
-
AUTHORIZATION
|
19
|
-
DEFLATE
|
20
|
-
GZIP
|
21
|
-
|
22
|
-
include
|
12
|
+
CONTENT_ENCODING = "content-encoding".freeze
|
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
|
+
APPLICATION_JSON = "application/json".freeze
|
18
|
+
AUTHORIZATION = "authorization".freeze
|
19
|
+
DEFLATE = "deflate".freeze
|
20
|
+
GZIP = "gzip".freeze
|
21
|
+
|
22
|
+
include Logging
|
23
23
|
|
24
24
|
attr_accessor :authentication
|
25
25
|
attr_reader :host, :port, :config
|
26
26
|
|
27
|
-
READ_EXCEPTIONS = [Timeout::Error, EOFError]
|
28
|
-
# This doesn't exist on Ruby 1.9.3
|
29
|
-
READ_EXCEPTIONS << Net::ReadTimeout if defined?(Net::ReadTimeout)
|
30
|
-
READ_EXCEPTIONS.freeze
|
27
|
+
READ_EXCEPTIONS = [Timeout::Error, EOFError, Net::ReadTimeout].freeze
|
31
28
|
|
32
29
|
class StartError < StandardError
|
33
30
|
attr_reader :original
|
34
31
|
|
35
|
-
def initialize(
|
36
|
-
@original =
|
37
|
-
super
|
32
|
+
def initialize(error)
|
33
|
+
@original = error
|
34
|
+
super error.inspect
|
38
35
|
end
|
39
|
-
|
40
36
|
end
|
41
37
|
|
42
|
-
class ReadResponseError < StandardError
|
38
|
+
class ReadResponseError < StandardError
|
39
|
+
end
|
43
40
|
|
44
41
|
def initialize(config, service = :auth, opts = {})
|
45
42
|
@config = config
|
46
43
|
|
47
|
-
unless url = config["#{service}_url"]
|
44
|
+
unless (url = config["#{service}_url"])
|
48
45
|
raise ArgumentError, "no URL specified for #{service}"
|
49
46
|
end
|
50
47
|
|
51
48
|
url = URI.parse(url)
|
52
49
|
|
53
|
-
@ssl
|
50
|
+
@ssl = url.scheme == "https"
|
54
51
|
@host = url.host
|
55
52
|
@port = url.port
|
56
53
|
|
57
|
-
if proxy_url = config[:proxy_url]
|
54
|
+
if (proxy_url = config[:proxy_url])
|
58
55
|
proxy_url = URI.parse(proxy_url)
|
59
|
-
@proxy_addr
|
60
|
-
@
|
56
|
+
@proxy_addr = proxy_url.host
|
57
|
+
@proxy_port = proxy_url.port
|
58
|
+
@proxy_user, @proxy_pass = (proxy_url.userinfo || "").split(/:/)
|
61
59
|
end
|
62
60
|
|
63
61
|
@open_timeout = get_timeout(:connect, config, service, opts)
|
64
62
|
@read_timeout = get_timeout(:read, config, service, opts)
|
65
63
|
|
66
64
|
@deflate = config["#{service}_http_deflate"]
|
67
|
-
@authentication = config[:
|
65
|
+
@authentication = config[:authentication]
|
68
66
|
end
|
69
67
|
|
70
68
|
def get(endpoint, hdrs = {})
|
@@ -82,25 +80,22 @@ module Skylight
|
|
82
80
|
execute(request, body)
|
83
81
|
end
|
84
82
|
|
85
|
-
|
83
|
+
private
|
86
84
|
|
87
85
|
def get_timeout(type, config, service, opts)
|
88
|
-
config.duration_ms("#{service}_http_#{type}_timeout") ||
|
89
|
-
opts[:timeout] || 15
|
86
|
+
config.duration_ms("#{service}_http_#{type}_timeout") || opts[:timeout] || 15
|
90
87
|
end
|
91
88
|
|
92
|
-
def build_request(type, endpoint, hdrs, length=nil)
|
89
|
+
def build_request(type, endpoint, hdrs, length = nil)
|
93
90
|
headers = {}
|
94
91
|
|
95
|
-
headers[CONTENT_LENGTH]
|
96
|
-
headers[AUTHORIZATION]
|
97
|
-
headers[ACCEPT]
|
98
|
-
headers[X_VERSION_HDR]
|
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
|
99
96
|
headers[CONTENT_ENCODING] = GZIP if length && @deflate
|
100
97
|
|
101
|
-
hdrs.each
|
102
|
-
headers[k] = v
|
103
|
-
end
|
98
|
+
hdrs.each { |k, v| headers[k] = v }
|
104
99
|
|
105
100
|
type.new(endpoint, headers)
|
106
101
|
end
|
@@ -108,7 +103,7 @@ module Skylight
|
|
108
103
|
def do_request(http, req)
|
109
104
|
begin
|
110
105
|
client = http.start
|
111
|
-
rescue => e
|
106
|
+
rescue StandardError => e
|
112
107
|
# TODO: Retry here
|
113
108
|
raise StartError, e
|
114
109
|
end
|
@@ -121,20 +116,24 @@ module Skylight
|
|
121
116
|
|
122
117
|
yield res
|
123
118
|
ensure
|
124
|
-
client
|
119
|
+
client&.finish
|
125
120
|
end
|
126
121
|
|
127
|
-
def execute(req, body=nil)
|
128
|
-
t
|
129
|
-
|
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
|
129
|
+
end
|
130
130
|
|
131
131
|
if body
|
132
132
|
body = Gzip.compress(body) if @deflate
|
133
133
|
req.body = body
|
134
134
|
end
|
135
135
|
|
136
|
-
http = Net::HTTP.new(@host, @port,
|
137
|
-
@proxy_addr, @proxy_port, @proxy_user, @proxy_pass)
|
136
|
+
http = Net::HTTP.new(@host, @port, @proxy_addr, @proxy_port, @proxy_user, @proxy_pass)
|
138
137
|
|
139
138
|
http.open_timeout = @open_timeout
|
140
139
|
http.read_timeout = @read_timeout
|
@@ -142,9 +141,7 @@ module Skylight
|
|
142
141
|
if @ssl
|
143
142
|
http.use_ssl = true
|
144
143
|
|
145
|
-
unless SSL.ca_cert_file?
|
146
|
-
http.ca_file = SSL.ca_cert_file_or_default
|
147
|
-
end
|
144
|
+
http.ca_file = SSL.ca_cert_file_or_default unless SSL.ca_cert_file?
|
148
145
|
|
149
146
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
150
147
|
end
|
@@ -167,7 +164,7 @@ module Skylight
|
|
167
164
|
attr_reader :status, :headers, :body, :exception
|
168
165
|
|
169
166
|
def initialize(status, headers, body)
|
170
|
-
@status
|
167
|
+
@status = status
|
171
168
|
@headers = headers
|
172
169
|
|
173
170
|
if (headers[CONTENT_TYPE] || "").include?(APPLICATION_JSON)
|
@@ -190,16 +187,10 @@ module Skylight
|
|
190
187
|
end
|
191
188
|
|
192
189
|
def get(key)
|
193
|
-
|
194
|
-
|
195
|
-
res = body
|
196
|
-
key.split('.').each do |part|
|
197
|
-
return unless res = res[part]
|
198
|
-
end
|
199
|
-
res
|
190
|
+
body.dig(*key.split(".")) if body.is_a?(Hash)
|
200
191
|
end
|
201
192
|
|
202
|
-
def respond_to_missing?(name, include_all=false)
|
193
|
+
def respond_to_missing?(name, include_all = false)
|
203
194
|
super || body.respond_to?(name, include_all)
|
204
195
|
end
|
205
196
|
|
@@ -212,16 +203,16 @@ module Skylight
|
|
212
203
|
end
|
213
204
|
end
|
214
205
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
206
|
+
ErrorResponse =
|
207
|
+
Struct.new(:request, :exception) do
|
208
|
+
def status
|
209
|
+
nil
|
210
|
+
end
|
219
211
|
|
220
|
-
|
221
|
-
|
212
|
+
def success?
|
213
|
+
false
|
214
|
+
end
|
222
215
|
end
|
223
|
-
end
|
224
|
-
|
225
216
|
end
|
226
217
|
end
|
227
218
|
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
|