skylight 5.0.1 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +395 -364
- data/CLA.md +1 -1
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +42 -54
- data/ext/libskylight.yml +9 -6
- data/lib/skylight.rb +20 -30
- data/lib/skylight/api.rb +22 -18
- data/lib/skylight/cli.rb +47 -46
- data/lib/skylight/cli/doctor.rb +50 -50
- data/lib/skylight/cli/helpers.rb +19 -19
- data/lib/skylight/cli/merger.rb +141 -139
- data/lib/skylight/config.rb +265 -300
- data/lib/skylight/deprecation.rb +4 -4
- data/lib/skylight/errors.rb +3 -4
- data/lib/skylight/extensions.rb +17 -29
- data/lib/skylight/extensions/source_location.rb +128 -128
- data/lib/skylight/formatters/http.rb +1 -3
- data/lib/skylight/gc.rb +30 -40
- data/lib/skylight/helpers.rb +43 -41
- data/lib/skylight/instrumenter.rb +25 -18
- data/lib/skylight/middleware.rb +31 -35
- data/lib/skylight/native.rb +8 -10
- data/lib/skylight/native_ext_fetcher.rb +10 -12
- data/lib/skylight/normalizers.rb +43 -39
- data/lib/skylight/normalizers/action_controller/process_action.rb +24 -25
- data/lib/skylight/normalizers/action_controller/send_file.rb +7 -6
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +7 -7
- data/lib/skylight/normalizers/active_job/perform.rb +48 -44
- data/lib/skylight/normalizers/active_model_serializers/render.rb +7 -3
- data/lib/skylight/normalizers/active_storage.rb +11 -13
- data/lib/skylight/normalizers/active_support/cache.rb +1 -12
- data/lib/skylight/normalizers/coach/handler_finish.rb +1 -3
- data/lib/skylight/normalizers/default.rb +1 -9
- data/lib/skylight/normalizers/faraday/request.rb +1 -3
- data/lib/skylight/normalizers/grape/endpoint.rb +13 -19
- data/lib/skylight/normalizers/grape/endpoint_run.rb +16 -18
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +1 -3
- data/lib/skylight/normalizers/graphql/base.rb +23 -28
- data/lib/skylight/normalizers/render.rb +19 -21
- data/lib/skylight/normalizers/shrine.rb +15 -17
- data/lib/skylight/normalizers/sql.rb +4 -4
- data/lib/skylight/probes.rb +38 -46
- data/lib/skylight/probes/action_controller.rb +32 -28
- data/lib/skylight/probes/action_dispatch/request_id.rb +9 -5
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +7 -5
- data/lib/skylight/probes/action_view.rb +9 -10
- data/lib/skylight/probes/active_job_enqueue.rb +3 -9
- data/lib/skylight/probes/active_model_serializers.rb +8 -8
- data/lib/skylight/probes/delayed_job.rb +37 -42
- data/lib/skylight/probes/elasticsearch.rb +3 -5
- data/lib/skylight/probes/excon.rb +1 -1
- data/lib/skylight/probes/excon/middleware.rb +22 -23
- data/lib/skylight/probes/graphql.rb +2 -7
- data/lib/skylight/probes/middleware.rb +14 -5
- data/lib/skylight/probes/mongo.rb +83 -91
- data/lib/skylight/probes/net_http.rb +1 -1
- data/lib/skylight/probes/redis.rb +5 -17
- data/lib/skylight/probes/sequel.rb +7 -11
- data/lib/skylight/probes/sinatra.rb +8 -5
- data/lib/skylight/probes/tilt.rb +2 -4
- data/lib/skylight/railtie.rb +121 -135
- data/lib/skylight/sidekiq.rb +4 -5
- data/lib/skylight/subscriber.rb +31 -33
- data/lib/skylight/test.rb +89 -84
- data/lib/skylight/trace.rb +121 -115
- data/lib/skylight/user_config.rb +14 -17
- data/lib/skylight/util/clock.rb +1 -0
- data/lib/skylight/util/component.rb +18 -21
- data/lib/skylight/util/deploy.rb +11 -13
- data/lib/skylight/util/http.rb +104 -105
- data/lib/skylight/util/logging.rb +4 -6
- data/lib/skylight/util/lru_cache.rb +2 -6
- data/lib/skylight/util/platform.rb +2 -6
- data/lib/skylight/util/ssl.rb +1 -25
- data/lib/skylight/version.rb +1 -1
- data/lib/skylight/vm/gc.rb +1 -9
- metadata +6 -6
data/lib/skylight/config.rb
CHANGED
@@ -22,112 +22,96 @@ module Skylight
|
|
22
22
|
# Map environment variable keys with Skylight configuration keys
|
23
23
|
ENV_TO_KEY = {
|
24
24
|
# == Authentication ==
|
25
|
-
-"AUTHENTICATION"
|
26
|
-
|
25
|
+
-"AUTHENTICATION" => :authentication,
|
27
26
|
# == App settings ==
|
28
|
-
-"ROOT"
|
29
|
-
-"HOSTNAME"
|
30
|
-
-"SESSION_TOKEN"
|
31
|
-
|
27
|
+
-"ROOT" => :root,
|
28
|
+
-"HOSTNAME" => :hostname,
|
29
|
+
-"SESSION_TOKEN" => :session_token,
|
32
30
|
# == Component settings ==
|
33
|
-
-"ENV"
|
34
|
-
-"COMPONENT"
|
35
|
-
-"REPORT_RAILS_ENV"
|
36
|
-
|
31
|
+
-"ENV" => :env,
|
32
|
+
-"COMPONENT" => :component,
|
33
|
+
-"REPORT_RAILS_ENV" => :report_rails_env,
|
37
34
|
# == Deploy settings ==
|
38
|
-
-"DEPLOY_ID"
|
39
|
-
-"DEPLOY_GIT_SHA"
|
40
|
-
-"DEPLOY_DESCRIPTION"
|
41
|
-
|
35
|
+
-"DEPLOY_ID" => :'deploy.id',
|
36
|
+
-"DEPLOY_GIT_SHA" => :'deploy.git_sha',
|
37
|
+
-"DEPLOY_DESCRIPTION" => :'deploy.description',
|
42
38
|
# == Logging ==
|
43
|
-
-"LOG_FILE"
|
44
|
-
-"LOG_LEVEL"
|
45
|
-
-"ALERT_LOG_FILE"
|
46
|
-
-"NATIVE_LOG_FILE"
|
47
|
-
-"NATIVE_LOG_LEVEL"
|
48
|
-
-"LOG_SQL_PARSE_ERRORS"
|
49
|
-
|
39
|
+
-"LOG_FILE" => :log_file,
|
40
|
+
-"LOG_LEVEL" => :log_level,
|
41
|
+
-"ALERT_LOG_FILE" => :alert_log_file,
|
42
|
+
-"NATIVE_LOG_FILE" => :native_log_file,
|
43
|
+
-"NATIVE_LOG_LEVEL" => :native_log_level,
|
44
|
+
-"LOG_SQL_PARSE_ERRORS" => :log_sql_parse_errors,
|
50
45
|
# == Proxy ==
|
51
|
-
-"PROXY_URL"
|
52
|
-
|
46
|
+
-"PROXY_URL" => :proxy_url,
|
53
47
|
# == Instrumenter ==
|
54
|
-
-"ENABLE_SEGMENTS"
|
55
|
-
-"ENABLE_SIDEKIQ"
|
56
|
-
-"IGNORED_ENDPOINT"
|
57
|
-
-"IGNORED_ENDPOINTS"
|
58
|
-
-"SINATRA_ROUTE_PREFIXES"
|
59
|
-
-"ENABLE_SOURCE_LOCATIONS"
|
60
|
-
|
48
|
+
-"ENABLE_SEGMENTS" => :enable_segments,
|
49
|
+
-"ENABLE_SIDEKIQ" => :enable_sidekiq,
|
50
|
+
-"IGNORED_ENDPOINT" => :ignored_endpoint,
|
51
|
+
-"IGNORED_ENDPOINTS" => :ignored_endpoints,
|
52
|
+
-"SINATRA_ROUTE_PREFIXES" => :sinatra_route_prefixes,
|
53
|
+
-"ENABLE_SOURCE_LOCATIONS" => :enable_source_locations,
|
61
54
|
# == Max Span Handling ==
|
62
|
-
-"REPORT_MAX_SPANS_EXCEEDED"
|
63
|
-
-"PRUNE_LARGE_TRACES"
|
64
|
-
|
55
|
+
-"REPORT_MAX_SPANS_EXCEEDED" => :report_max_spans_exceeded,
|
56
|
+
-"PRUNE_LARGE_TRACES" => :prune_large_traces,
|
65
57
|
# == Skylight Remote ==
|
66
|
-
-"AUTH_URL"
|
67
|
-
-"APP_CREATE_URL"
|
68
|
-
-"MERGES_URL"
|
69
|
-
-"VALIDATION_URL"
|
70
|
-
-"AUTH_HTTP_DEFLATE"
|
71
|
-
-"AUTH_HTTP_CONNECT_TIMEOUT"
|
72
|
-
-"AUTH_HTTP_READ_TIMEOUT"
|
73
|
-
-"REPORT_URL"
|
74
|
-
-"REPORT_HTTP_DEFLATE"
|
75
|
-
-"REPORT_HTTP_CONNECT_TIMEOUT"
|
76
|
-
-"REPORT_HTTP_READ_TIMEOUT"
|
77
|
-
-"REPORT_HTTP_DISABLED"
|
78
|
-
|
58
|
+
-"AUTH_URL" => :auth_url,
|
59
|
+
-"APP_CREATE_URL" => :app_create_url,
|
60
|
+
-"MERGES_URL" => :merges_url,
|
61
|
+
-"VALIDATION_URL" => :validation_url,
|
62
|
+
-"AUTH_HTTP_DEFLATE" => :auth_http_deflate,
|
63
|
+
-"AUTH_HTTP_CONNECT_TIMEOUT" => :auth_http_connect_timeout,
|
64
|
+
-"AUTH_HTTP_READ_TIMEOUT" => :auth_http_read_timeout,
|
65
|
+
-"REPORT_URL" => :report_url,
|
66
|
+
-"REPORT_HTTP_DEFLATE" => :report_http_deflate,
|
67
|
+
-"REPORT_HTTP_CONNECT_TIMEOUT" => :report_http_connect_timeout,
|
68
|
+
-"REPORT_HTTP_READ_TIMEOUT" => :report_http_read_timeout,
|
69
|
+
-"REPORT_HTTP_DISABLED" => :report_http_disabled,
|
79
70
|
# == Native agent settings ==
|
80
71
|
#
|
81
|
-
-"LAZY_START"
|
82
|
-
-"DAEMON_EXEC_PATH"
|
83
|
-
-"DAEMON_LIB_PATH"
|
84
|
-
-"PIDFILE_PATH"
|
85
|
-
-"SOCKDIR_PATH"
|
86
|
-
-"BATCH_QUEUE_DEPTH"
|
87
|
-
-"BATCH_SAMPLE_SIZE"
|
88
|
-
-"BATCH_FLUSH_INTERVAL"
|
89
|
-
-"DAEMON_TICK_INTERVAL"
|
90
|
-
-"DAEMON_LOCK_CHECK_INTERVAL"
|
91
|
-
-"DAEMON_INACTIVITY_TIMEOUT"
|
92
|
-
-"CLIENT_MAX_TRIES"
|
93
|
-
-"CLIENT_CONN_TRY_WIN"
|
94
|
-
-"MAX_PRESPAWN_JITTER"
|
95
|
-
-"DAEMON_WAIT_TIMEOUT"
|
96
|
-
-"CLIENT_CHECK_INTERVAL"
|
97
|
-
-"CLIENT_QUEUE_DEPTH"
|
98
|
-
-"CLIENT_WRITE_TIMEOUT"
|
99
|
-
-"SSL_CERT_PATH"
|
100
|
-
-"
|
101
|
-
|
72
|
+
-"LAZY_START" => :'daemon.lazy_start',
|
73
|
+
-"DAEMON_EXEC_PATH" => :'daemon.exec_path',
|
74
|
+
-"DAEMON_LIB_PATH" => :'daemon.lib_path',
|
75
|
+
-"PIDFILE_PATH" => :'daemon.pidfile_path',
|
76
|
+
-"SOCKDIR_PATH" => :'daemon.sockdir_path',
|
77
|
+
-"BATCH_QUEUE_DEPTH" => :'daemon.batch_queue_depth',
|
78
|
+
-"BATCH_SAMPLE_SIZE" => :'daemon.batch_sample_size',
|
79
|
+
-"BATCH_FLUSH_INTERVAL" => :'daemon.batch_flush_interval',
|
80
|
+
-"DAEMON_TICK_INTERVAL" => :'daemon.tick_interval',
|
81
|
+
-"DAEMON_LOCK_CHECK_INTERVAL" => :'daemon.lock_check_interval',
|
82
|
+
-"DAEMON_INACTIVITY_TIMEOUT" => :'daemon.inactivity_timeout',
|
83
|
+
-"CLIENT_MAX_TRIES" => :'daemon.max_connect_tries',
|
84
|
+
-"CLIENT_CONN_TRY_WIN" => :'daemon.connect_try_window',
|
85
|
+
-"MAX_PRESPAWN_JITTER" => :'daemon.max_prespawn_jitter',
|
86
|
+
-"DAEMON_WAIT_TIMEOUT" => :'daemon.wait_timeout',
|
87
|
+
-"CLIENT_CHECK_INTERVAL" => :'daemon.client_check_interval',
|
88
|
+
-"CLIENT_QUEUE_DEPTH" => :'daemon.client_queue_depth',
|
89
|
+
-"CLIENT_WRITE_TIMEOUT" => :'daemon.client_write_timeout',
|
90
|
+
-"SSL_CERT_PATH" => :'daemon.ssl_cert_path',
|
91
|
+
-"ENABLE_TCP" => :'daemon.enable_tcp',
|
92
|
+
-"TCP_PORT" => :'daemon.tcp_port',
|
102
93
|
# == Legacy env vars ==
|
103
94
|
#
|
104
|
-
-"AGENT_LOCKFILE"
|
105
|
-
-"AGENT_SOCKFILE_PATH"
|
106
|
-
|
95
|
+
-"AGENT_LOCKFILE" => :'agent.lockfile',
|
96
|
+
-"AGENT_SOCKFILE_PATH" => :'agent.sockfile_path',
|
107
97
|
# == User config settings ==
|
108
|
-
-"USER_CONFIG_PATH"
|
109
|
-
|
98
|
+
-"USER_CONFIG_PATH" => :user_config_path,
|
110
99
|
# == Heroku settings ==
|
111
|
-
-"HEROKU_DYNO_INFO_PATH"
|
112
|
-
|
100
|
+
-"HEROKU_DYNO_INFO_PATH" => :'heroku.dyno_info_path',
|
113
101
|
# == Source Location ==
|
114
102
|
-"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems,
|
115
|
-
-"SOURCE_LOCATION_CACHE_SIZE"
|
103
|
+
-"SOURCE_LOCATION_CACHE_SIZE" => :source_location_cache_size
|
116
104
|
}.freeze
|
117
105
|
|
118
106
|
KEY_TO_NATIVE_ENV = {
|
119
107
|
# We use different log files for native and Ruby, but the native code doesn't know this
|
120
|
-
native_log_file:
|
108
|
+
native_log_file: "LOG_FILE",
|
121
109
|
native_log_level: "LOG_LEVEL"
|
122
110
|
}.freeze
|
123
111
|
|
124
112
|
SERVER_VALIDATE = %i[].freeze
|
125
113
|
|
126
|
-
DEFAULT_IGNORED_SOURCE_LOCATION_GEMS = [
|
127
|
-
-"skylight",
|
128
|
-
-"activesupport",
|
129
|
-
-"activerecord"
|
130
|
-
].freeze
|
114
|
+
DEFAULT_IGNORED_SOURCE_LOCATION_GEMS = [-"skylight", -"activesupport", -"activerecord"].freeze
|
131
115
|
|
132
116
|
# Default values for Skylight configuration keys
|
133
117
|
def self.default_values
|
@@ -135,39 +119,32 @@ module Skylight
|
|
135
119
|
begin
|
136
120
|
ret = {
|
137
121
|
# URLs
|
138
|
-
auth_url:
|
139
|
-
app_create_url:
|
140
|
-
merges_url:
|
141
|
-
validation_url:
|
142
|
-
|
122
|
+
auth_url: -"https://auth.skylight.io/agent",
|
123
|
+
app_create_url: -"https://www.skylight.io/apps",
|
124
|
+
merges_url: -"https://www.skylight.io/merges",
|
125
|
+
validation_url: -"https://auth.skylight.io/agent/config",
|
143
126
|
# Logging
|
144
|
-
log_file:
|
145
|
-
log_level:
|
146
|
-
alert_log_file:
|
147
|
-
log_sql_parse_errors:
|
148
|
-
native_log_level:
|
149
|
-
|
127
|
+
log_file: -"-",
|
128
|
+
log_level: -"INFO",
|
129
|
+
alert_log_file: -"-",
|
130
|
+
log_sql_parse_errors: true,
|
131
|
+
native_log_level: -"warn",
|
150
132
|
# Features
|
151
|
-
enable_segments:
|
152
|
-
enable_sidekiq:
|
153
|
-
sinatra_route_prefixes:
|
154
|
-
enable_source_locations:
|
155
|
-
|
133
|
+
enable_segments: true,
|
134
|
+
enable_sidekiq: false,
|
135
|
+
sinatra_route_prefixes: false,
|
136
|
+
enable_source_locations: true,
|
156
137
|
# Deploys
|
157
|
-
'heroku.dyno_info_path':
|
158
|
-
report_rails_env:
|
159
|
-
|
138
|
+
'heroku.dyno_info_path': -"/etc/heroku/dyno",
|
139
|
+
report_rails_env: true,
|
160
140
|
# Daemon
|
161
|
-
'daemon.lazy_start':
|
162
|
-
hostname:
|
141
|
+
'daemon.lazy_start': true,
|
142
|
+
hostname: Util::Hostname.default_hostname,
|
163
143
|
report_max_spans_exceeded: false,
|
164
|
-
prune_large_traces:
|
144
|
+
prune_large_traces: true
|
165
145
|
}
|
166
146
|
|
167
|
-
unless Util::Platform::OS == -"darwin"
|
168
|
-
ret[:'daemon.ssl_cert_path'] = Util::SSL.ca_cert_file_or_default
|
169
|
-
ret[:'daemon.ssl_cert_dir'] = Util::SSL.ca_cert_dir
|
170
|
-
end
|
147
|
+
ret[:'daemon.ssl_cert_path'] = Util::SSL.ca_cert_file_or_default unless Util::Platform::OS == -"darwin"
|
171
148
|
|
172
149
|
if Skylight.native?
|
173
150
|
native_path = Skylight.libskylight_path
|
@@ -182,65 +159,64 @@ module Skylight
|
|
182
159
|
|
183
160
|
REQUIRED_KEYS = {
|
184
161
|
authentication: "authentication token",
|
185
|
-
hostname:
|
186
|
-
auth_url:
|
162
|
+
hostname: "server hostname",
|
163
|
+
auth_url: "authentication url",
|
187
164
|
validation_url: "config validation url"
|
188
165
|
}.freeze
|
189
166
|
|
190
167
|
def self.native_env_keys
|
191
|
-
@native_env_keys ||=
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
168
|
+
@native_env_keys ||=
|
169
|
+
%i[
|
170
|
+
native_log_level
|
171
|
+
native_log_file
|
172
|
+
log_sql_parse_errors
|
173
|
+
version
|
174
|
+
root
|
175
|
+
proxy_url
|
176
|
+
hostname
|
177
|
+
session_token
|
178
|
+
auth_url
|
179
|
+
auth_http_deflate
|
180
|
+
auth_http_connect_timeout
|
181
|
+
auth_http_read_timeout
|
182
|
+
report_url
|
183
|
+
report_http_deflate
|
184
|
+
report_http_connect_timeout
|
185
|
+
report_http_read_timeout
|
186
|
+
report_http_disabled
|
187
|
+
daemon.lazy_start
|
188
|
+
daemon.exec_path
|
189
|
+
daemon.lib_path
|
190
|
+
daemon.pidfile_path
|
191
|
+
daemon.sockdir_path
|
192
|
+
daemon.batch_queue_depth
|
193
|
+
daemon.batch_sample_size
|
194
|
+
daemon.batch_flush_interval
|
195
|
+
daemon.tick_interval
|
196
|
+
daemon.lock_check_interval
|
197
|
+
daemon.inactivity_timeout
|
198
|
+
daemon.max_connect_tries
|
199
|
+
daemon.connect_try_window
|
200
|
+
daemon.max_prespawn_jitter
|
201
|
+
daemon.wait_timeout
|
202
|
+
daemon.client_check_interval
|
203
|
+
daemon.client_queue_depth
|
204
|
+
daemon.client_write_timeout
|
205
|
+
daemon.ssl_cert_path
|
206
|
+
daemon.ssl_cert_dir
|
207
|
+
daemon.enable_tcp
|
208
|
+
daemon.tcp_port
|
209
|
+
]
|
230
210
|
end
|
231
211
|
|
232
212
|
# Maps legacy config keys to new config keys
|
233
213
|
def self.legacy_keys
|
234
|
-
@legacy_keys ||= {
|
235
|
-
'agent.sockfile_path': :'daemon.sockdir_path',
|
236
|
-
'agent.lockfile': :'daemon.pidfile_path'
|
237
|
-
}
|
214
|
+
@legacy_keys ||= { 'agent.sockfile_path': :'daemon.sockdir_path', 'agent.lockfile': :'daemon.pidfile_path' }
|
238
215
|
end
|
239
216
|
|
240
217
|
def self.validators
|
241
|
-
@validators ||=
|
242
|
-
'agent.interval': [->(v, _c) { v.is_a?(Integer) && v > 0 }, "must be an integer greater than 0"]
|
243
|
-
}
|
218
|
+
@validators ||=
|
219
|
+
{ 'agent.interval': [->(v, _c) { v.is_a?(Integer) && v > 0 }, "must be an integer greater than 0"] }
|
244
220
|
end
|
245
221
|
|
246
222
|
# @api private
|
@@ -250,9 +226,7 @@ module Skylight
|
|
250
226
|
def initialize(*args)
|
251
227
|
attrs = {}
|
252
228
|
|
253
|
-
if args.last.is_a?(Hash)
|
254
|
-
attrs = args.pop.dup
|
255
|
-
end
|
229
|
+
attrs = args.pop.dup if args.last.is_a?(Hash)
|
256
230
|
|
257
231
|
@values = {}
|
258
232
|
@priority = {}
|
@@ -266,13 +240,9 @@ module Skylight
|
|
266
240
|
@priority_regexp = /^#{Regexp.escape(priority_key)}\.(.+)$/
|
267
241
|
end
|
268
242
|
|
269
|
-
attrs.each
|
270
|
-
self[k] = v
|
271
|
-
end
|
243
|
+
attrs.each { |k, v| self[k] = v }
|
272
244
|
|
273
|
-
p&.each
|
274
|
-
@priority[self.class.remap_key(k)] = v
|
275
|
-
end
|
245
|
+
p&.each { |k, v| @priority[self.class.remap_key(k)] = v }
|
276
246
|
end
|
277
247
|
|
278
248
|
def self.load(opts = {}, env = ENV)
|
@@ -284,10 +254,8 @@ module Skylight
|
|
284
254
|
if path
|
285
255
|
error = nil
|
286
256
|
begin
|
287
|
-
attrs =
|
288
|
-
|
289
|
-
[], # permitted_symbols
|
290
|
-
true) # aliases enabled
|
257
|
+
attrs =
|
258
|
+
YAML.safe_load(ERB.new(File.read(path)).result, permitted_classes: [], permitted_symbols: [], aliases: true)
|
291
259
|
error = "empty file" unless attrs
|
292
260
|
error = "invalid format" if attrs && !attrs.is_a?(Hash)
|
293
261
|
rescue Exception => e
|
@@ -300,15 +268,11 @@ module Skylight
|
|
300
268
|
# The key-value pairs in this `priority` option are inserted into the
|
301
269
|
# config's @priority hash *after* anything listed under priority_key;
|
302
270
|
# i.e., ENV takes precendence over priority_key
|
303
|
-
if env
|
304
|
-
attrs[:priority] = remap_env(env)
|
305
|
-
end
|
271
|
+
attrs[:priority] = remap_env(env) if env
|
306
272
|
|
307
273
|
config = new(priority_key, attrs)
|
308
274
|
|
309
|
-
opts.each
|
310
|
-
config[k] = v
|
311
|
-
end
|
275
|
+
opts.each { |k, v| config[k] = v }
|
312
276
|
|
313
277
|
config
|
314
278
|
end
|
@@ -335,12 +299,18 @@ module Skylight
|
|
335
299
|
|
336
300
|
ret[key] =
|
337
301
|
case val
|
338
|
-
when /^false$/i
|
339
|
-
|
340
|
-
when /^
|
341
|
-
|
342
|
-
when
|
343
|
-
|
302
|
+
when /^false$/i
|
303
|
+
false
|
304
|
+
when /^true$/i
|
305
|
+
true
|
306
|
+
when /^(nil|null)$/i
|
307
|
+
nil
|
308
|
+
when /^\d+$/
|
309
|
+
val.to_i
|
310
|
+
when /^\d+\.\d+$/
|
311
|
+
val.to_f
|
312
|
+
else
|
313
|
+
val
|
344
314
|
end
|
345
315
|
end
|
346
316
|
|
@@ -349,11 +319,7 @@ module Skylight
|
|
349
319
|
|
350
320
|
# @api private
|
351
321
|
def validate!
|
352
|
-
REQUIRED_KEYS.each
|
353
|
-
unless get(k)
|
354
|
-
raise ConfigError, "#{v} required"
|
355
|
-
end
|
356
|
-
end
|
322
|
+
REQUIRED_KEYS.each { |k, v| raise ConfigError, "#{v} required" unless get(k) }
|
357
323
|
|
358
324
|
log_file = self[:log_file]
|
359
325
|
alert_log_file = self[:alert_log_file]
|
@@ -361,6 +327,7 @@ module Skylight
|
|
361
327
|
|
362
328
|
check_logfile_permissions(log_file, "log_file")
|
363
329
|
check_logfile_permissions(alert_log_file, "alert_log_file")
|
330
|
+
|
364
331
|
# TODO: Support rotation interpolation in this check
|
365
332
|
check_logfile_permissions(native_log_file, "native_log_file")
|
366
333
|
|
@@ -380,15 +347,20 @@ module Skylight
|
|
380
347
|
file_root = File.dirname(file)
|
381
348
|
|
382
349
|
# Try to make the directory, don't blow up if we can't. Our writable? check will fail later.
|
383
|
-
|
350
|
+
begin
|
351
|
+
FileUtils.mkdir_p file_root
|
352
|
+
rescue StandardError
|
353
|
+
nil
|
354
|
+
end
|
384
355
|
|
385
356
|
if File.exist?(file) && !FileTest.writable?(file)
|
386
357
|
raise ConfigError, "File `#{file}` is not writable. Please set #{key} in your config to a writable path"
|
387
358
|
end
|
388
359
|
|
389
360
|
unless FileTest.writable?(file_root)
|
390
|
-
raise ConfigError,
|
391
|
-
|
361
|
+
raise ConfigError,
|
362
|
+
"Directory `#{file_root}` is not writable. Please set #{key} in your config to a " \
|
363
|
+
"writable path"
|
392
364
|
end
|
393
365
|
end
|
394
366
|
|
@@ -408,7 +380,7 @@ module Skylight
|
|
408
380
|
key = self.class.remap_key(key)
|
409
381
|
|
410
382
|
return @priority[key] if @priority.key?(key)
|
411
|
-
return @values[key]
|
383
|
+
return @values[key] if @values.key?(key)
|
412
384
|
return self.class.default_values[key] if self.class.default_values.key?(key)
|
413
385
|
|
414
386
|
if default
|
@@ -423,14 +395,10 @@ module Skylight
|
|
423
395
|
alias [] get
|
424
396
|
|
425
397
|
def set(key, val, scope = nil)
|
426
|
-
if scope
|
427
|
-
key = [scope, key].join(".")
|
428
|
-
end
|
398
|
+
key = [scope, key].join(".") if scope
|
429
399
|
|
430
400
|
if val.is_a?(Hash)
|
431
|
-
val.each
|
432
|
-
set(k, v, key)
|
433
|
-
end
|
401
|
+
val.each { |k, v| set(k, v, key) }
|
434
402
|
else
|
435
403
|
k = self.class.remap_key(key)
|
436
404
|
|
@@ -444,9 +412,7 @@ module Skylight
|
|
444
412
|
end
|
445
413
|
end
|
446
414
|
|
447
|
-
if @priority_regexp && k =~ @priority_regexp
|
448
|
-
@priority[$1.to_sym] = val
|
449
|
-
end
|
415
|
+
@priority[$1.to_sym] = val if @priority_regexp && k =~ @priority_regexp
|
450
416
|
|
451
417
|
@values[k] = val
|
452
418
|
end
|
@@ -468,7 +434,8 @@ module Skylight
|
|
468
434
|
v / 1_000
|
469
435
|
when "nanos"
|
470
436
|
v / 1_000_000
|
471
|
-
else
|
437
|
+
else
|
438
|
+
# "s", "sec", nil
|
472
439
|
v * 1000
|
473
440
|
end
|
474
441
|
else
|
@@ -479,13 +446,16 @@ module Skylight
|
|
479
446
|
def to_native_env
|
480
447
|
ret = []
|
481
448
|
|
482
|
-
self
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
449
|
+
self
|
450
|
+
.class
|
451
|
+
.native_env_keys
|
452
|
+
.each do |key|
|
453
|
+
value = send_or_get(key)
|
454
|
+
unless value.nil?
|
455
|
+
env_key = KEY_TO_NATIVE_ENV[key] || ENV_TO_KEY.key(key) || key.upcase
|
456
|
+
ret << "SKYLIGHT_#{env_key}" << cast_for_env(value)
|
457
|
+
end
|
487
458
|
end
|
488
|
-
end
|
489
459
|
|
490
460
|
ret << "SKYLIGHT_AUTHENTICATION" << authentication_with_meta
|
491
461
|
ret << "SKYLIGHT_VALIDATE_AUTHENTICATION" << "false"
|
@@ -516,9 +486,7 @@ module Skylight
|
|
516
486
|
|
517
487
|
# If, for some odd reason you have a comma in your endpoint name, use the
|
518
488
|
# YML config instead.
|
519
|
-
if ignored_endpoints.is_a?(String)
|
520
|
-
ignored_endpoints = ignored_endpoints.split(/\s*,\s*/)
|
521
|
-
end
|
489
|
+
ignored_endpoints = ignored_endpoints.split(/\s*,\s*/) if ignored_endpoints.is_a?(String)
|
522
490
|
|
523
491
|
val = Array(get(:ignored_endpoint))
|
524
492
|
val.concat(Array(ignored_endpoints))
|
@@ -531,9 +499,7 @@ module Skylight
|
|
531
499
|
@source_location_ignored_gems ||=
|
532
500
|
begin
|
533
501
|
ignored_gems = get(:source_location_ignored_gems)
|
534
|
-
if ignored_gems.is_a?(String)
|
535
|
-
ignored_gems = ignored_gems.split(/\s*,\s*/)
|
536
|
-
end
|
502
|
+
ignored_gems = ignored_gems.split(/\s*,\s*/) if ignored_gems.is_a?(String)
|
537
503
|
|
538
504
|
Array(ignored_gems) | DEFAULT_IGNORED_SOURCE_LOCATION_GEMS
|
539
505
|
end
|
@@ -549,12 +515,18 @@ module Skylight
|
|
549
515
|
Logger::DEBUG
|
550
516
|
else
|
551
517
|
case get(:log_level)
|
552
|
-
when /^debug$/i
|
553
|
-
|
554
|
-
when /^
|
555
|
-
|
556
|
-
when /^
|
557
|
-
|
518
|
+
when /^debug$/i
|
519
|
+
Logger::DEBUG
|
520
|
+
when /^info$/i
|
521
|
+
Logger::INFO
|
522
|
+
when /^warn$/i
|
523
|
+
Logger::WARN
|
524
|
+
when /^error$/i
|
525
|
+
Logger::ERROR
|
526
|
+
when /^fatal$/i
|
527
|
+
Logger::FATAL
|
528
|
+
else
|
529
|
+
Logger::ERROR
|
558
530
|
end
|
559
531
|
end
|
560
532
|
end
|
@@ -564,36 +536,35 @@ module Skylight
|
|
564
536
|
end
|
565
537
|
|
566
538
|
def logger
|
567
|
-
@logger ||=
|
568
|
-
MUTEX.synchronize do
|
569
|
-
load_logger
|
570
|
-
end
|
539
|
+
@logger ||= MUTEX.synchronize { load_logger }
|
571
540
|
end
|
572
541
|
|
573
542
|
def native_log_file
|
574
|
-
@native_log_file ||=
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
543
|
+
@native_log_file ||=
|
544
|
+
get("native_log_file") do
|
545
|
+
log_file = self["log_file"]
|
546
|
+
return "-" if log_file == "-"
|
547
|
+
|
548
|
+
parts = log_file.to_s.split(".")
|
549
|
+
parts.insert(-2, "native")
|
550
|
+
parts.join(".")
|
551
|
+
end
|
582
552
|
end
|
583
553
|
|
584
554
|
attr_writer :logger, :alert_logger
|
585
555
|
|
586
556
|
def alert_logger
|
587
|
-
@alert_logger ||=
|
588
|
-
|
589
|
-
|
590
|
-
|
557
|
+
@alert_logger ||=
|
558
|
+
MUTEX.synchronize do
|
559
|
+
unless (l = @alert_logger)
|
560
|
+
out = get(:alert_log_file)
|
561
|
+
out = Util::AlertLogger.new(load_logger) if out == "-"
|
591
562
|
|
592
|
-
|
593
|
-
|
563
|
+
l = create_logger(out, level: Logger::DEBUG)
|
564
|
+
end
|
594
565
|
|
595
|
-
|
596
|
-
|
566
|
+
l
|
567
|
+
end
|
597
568
|
end
|
598
569
|
|
599
570
|
def enable_segments?
|
@@ -622,36 +593,41 @@ module Skylight
|
|
622
593
|
|
623
594
|
private
|
624
595
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
# May be redundant since we also do this in the permissions check
|
629
|
-
FileUtils.mkdir_p(File.dirname(out))
|
630
|
-
end
|
596
|
+
def create_logger(out, level: :info)
|
597
|
+
if out.is_a?(String)
|
598
|
+
out = File.expand_path(out, root)
|
631
599
|
|
632
|
-
|
633
|
-
|
634
|
-
Logger.new($stdout, progname: "Skylight", level: level)
|
600
|
+
# May be redundant since we also do this in the permissions check
|
601
|
+
FileUtils.mkdir_p(File.dirname(out))
|
635
602
|
end
|
636
603
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
l = create_logger(out, level: log_level)
|
642
|
-
end
|
604
|
+
Logger.new(out, progname: "Skylight", level: level)
|
605
|
+
rescue StandardError
|
606
|
+
Logger.new($stdout, progname: "Skylight", level: level)
|
607
|
+
end
|
643
608
|
|
644
|
-
|
609
|
+
def load_logger
|
610
|
+
unless (l = @logger)
|
611
|
+
out = get(:log_file)
|
612
|
+
out = $stdout if out == "-"
|
613
|
+
l = create_logger(out, level: log_level)
|
645
614
|
end
|
646
615
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
616
|
+
l
|
617
|
+
end
|
618
|
+
|
619
|
+
def cast_for_env(val)
|
620
|
+
case val
|
621
|
+
when true
|
622
|
+
"true"
|
623
|
+
when false
|
624
|
+
"false"
|
625
|
+
when nil
|
626
|
+
"nil"
|
627
|
+
else
|
628
|
+
val.to_s
|
654
629
|
end
|
630
|
+
end
|
655
631
|
|
656
632
|
public
|
657
633
|
|
@@ -668,15 +644,11 @@ module Skylight
|
|
668
644
|
return false
|
669
645
|
end
|
670
646
|
|
671
|
-
if res.error_response?
|
672
|
-
warn("Unable to reach server for config validation")
|
673
|
-
end
|
647
|
+
warn("Unable to reach server for config validation") if res.error_response?
|
674
648
|
|
675
649
|
unless res.config_valid?
|
676
650
|
warn("Invalid configuration") unless res.error_response?
|
677
|
-
res.validation_errors.each
|
678
|
-
warn(" #{k}: #{v}")
|
679
|
-
end
|
651
|
+
res.validation_errors.each { |k, v| warn(" #{k}: #{v}") }
|
680
652
|
|
681
653
|
return false if res.forbidden?
|
682
654
|
|
@@ -705,29 +677,33 @@ module Skylight
|
|
705
677
|
|
706
678
|
def check_sockdir_permissions(sockdir_path)
|
707
679
|
# Try to make the directory, don't blow up if we can't. Our writable? check will fail later.
|
708
|
-
|
680
|
+
begin
|
681
|
+
FileUtils.mkdir_p sockdir_path
|
682
|
+
rescue StandardError
|
683
|
+
nil
|
684
|
+
end
|
709
685
|
|
710
686
|
unless FileTest.writable?(sockdir_path)
|
711
|
-
raise ConfigError,
|
712
|
-
|
687
|
+
raise ConfigError,
|
688
|
+
"Directory `#{sockdir_path}` is not writable. Please set daemon.sockdir_path in " \
|
689
|
+
"your config to a writable path"
|
713
690
|
end
|
714
691
|
|
715
692
|
if check_nfs(sockdir_path)
|
716
|
-
raise ConfigError,
|
717
|
-
|
693
|
+
raise ConfigError,
|
694
|
+
"Directory `#{sockdir_path}` is an NFS mount and will not allow sockets. Please set " \
|
695
|
+
"daemon.sockdir_path in your config to a non-NFS path."
|
718
696
|
end
|
719
697
|
end
|
720
698
|
|
721
699
|
def write(path)
|
722
700
|
FileUtils.mkdir_p(File.dirname(path))
|
723
701
|
|
724
|
-
File.open(path, "w")
|
725
|
-
f.puts <<~YAML
|
702
|
+
File.open(path, "w") { |f| f.puts <<~YAML }
|
726
703
|
---
|
727
704
|
# The authentication token for the application.
|
728
705
|
authentication: #{self[:authentication]}
|
729
706
|
YAML
|
730
|
-
end
|
731
707
|
end
|
732
708
|
|
733
709
|
#
|
@@ -757,17 +733,11 @@ module Skylight
|
|
757
733
|
end
|
758
734
|
|
759
735
|
def components
|
760
|
-
@components ||=
|
761
|
-
|
762
|
-
get(:env),
|
763
|
-
Util::Component
|
764
|
-
|
765
|
-
worker: Util::Component.new(
|
766
|
-
get(:env),
|
767
|
-
get(:component) || get(:worker_component),
|
768
|
-
force_worker: true
|
769
|
-
)
|
770
|
-
}
|
736
|
+
@components ||=
|
737
|
+
{
|
738
|
+
web: Util::Component.new(get(:env), Util::Component::DEFAULT_NAME),
|
739
|
+
worker: Util::Component.new(get(:env), get(:component) || get(:worker_component), force_worker: true)
|
740
|
+
}
|
771
741
|
rescue ArgumentError => e
|
772
742
|
raise ConfigError, e.message
|
773
743
|
end
|
@@ -781,25 +751,20 @@ module Skylight
|
|
781
751
|
end
|
782
752
|
|
783
753
|
def as_json(*)
|
784
|
-
{
|
785
|
-
config: {
|
786
|
-
priority: @priority.merge(component.as_json),
|
787
|
-
values: @values
|
788
|
-
}
|
789
|
-
}
|
754
|
+
{ config: { priority: @priority.merge(component.as_json), values: @values } }
|
790
755
|
end
|
791
756
|
|
792
757
|
private
|
793
758
|
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
759
|
+
def check_nfs(path)
|
760
|
+
# Should work on most *nix, though not on OS X
|
761
|
+
`stat -f -L -c %T #{path} 2>&1`.strip == "nfs"
|
762
|
+
end
|
798
763
|
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
764
|
+
def reporting_env?
|
765
|
+
# true if env was explicitly set,
|
766
|
+
# or if we are auto-detecting via the opt-in SKYLIGHT_REPORT_RAILS_ENV=true
|
767
|
+
!!(get(:report_rails_env) || get(:env))
|
768
|
+
end
|
804
769
|
end
|
805
770
|
end
|