skylight 5.0.1 → 5.1.1
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 +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
|