skylight 4.2.2 → 5.0.0.beta2
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 +29 -0
- data/CONTRIBUTING.md +1 -7
- data/ext/extconf.rb +6 -5
- data/ext/libskylight.yml +5 -6
- data/ext/skylight_native.c +24 -100
- data/lib/skylight.rb +204 -14
- data/lib/skylight/api.rb +7 -3
- data/lib/skylight/cli.rb +4 -3
- data/lib/skylight/cli/doctor.rb +13 -14
- data/lib/skylight/cli/merger.rb +6 -4
- data/lib/skylight/config.rb +604 -127
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +17 -2
- data/lib/skylight/extensions.rb +107 -0
- data/lib/skylight/extensions/source_location.rb +280 -0
- data/lib/skylight/formatters/http.rb +19 -0
- data/lib/skylight/gc.rb +109 -0
- data/lib/skylight/helpers.rb +18 -2
- data/lib/skylight/instrumenter.rb +326 -15
- data/lib/skylight/middleware.rb +138 -1
- data/lib/skylight/native.rb +51 -1
- data/lib/skylight/native_ext_fetcher.rb +4 -3
- data/lib/skylight/normalizers.rb +151 -0
- data/lib/skylight/normalizers/action_controller/process_action.rb +69 -0
- data/lib/skylight/normalizers/action_controller/send_file.rb +50 -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 +86 -0
- data/lib/skylight/normalizers/active_model_serializers/render.rb +28 -0
- data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
- data/lib/skylight/normalizers/active_record/sql.rb +12 -0
- data/lib/skylight/normalizers/active_storage.rb +30 -0
- data/lib/skylight/normalizers/active_support/cache.rb +22 -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 +46 -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 +32 -0
- data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
- data/lib/skylight/normalizers/faraday/request.rb +40 -0
- data/lib/skylight/normalizers/grape/endpoint.rb +34 -0
- data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
- data/lib/skylight/normalizers/grape/endpoint_run.rb +41 -0
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +22 -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 +132 -0
- data/lib/skylight/normalizers/render.rb +81 -0
- data/lib/skylight/normalizers/sequel/sql.rb +12 -0
- data/lib/skylight/normalizers/sql.rb +45 -0
- data/lib/skylight/probes.rb +181 -0
- data/lib/skylight/probes/action_controller.rb +48 -0
- data/lib/skylight/probes/action_dispatch.rb +2 -0
- data/lib/skylight/probes/action_dispatch/request_id.rb +29 -0
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +28 -0
- data/lib/skylight/probes/action_view.rb +43 -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/delayed_job.rb +148 -0
- data/lib/skylight/probes/elasticsearch.rb +38 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/excon/middleware.rb +66 -0
- data/lib/skylight/probes/faraday.rb +23 -0
- data/lib/skylight/probes/graphql.rb +43 -0
- data/lib/skylight/probes/httpclient.rb +44 -0
- data/lib/skylight/probes/middleware.rb +126 -0
- data/lib/skylight/probes/mongo.rb +163 -0
- data/lib/skylight/probes/mongoid.rb +13 -0
- data/lib/skylight/probes/net_http.rb +54 -0
- data/lib/skylight/probes/redis.rb +60 -0
- data/lib/skylight/probes/sequel.rb +33 -0
- data/lib/skylight/probes/sinatra.rb +63 -0
- data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
- data/lib/skylight/probes/tilt.rb +27 -0
- data/lib/skylight/railtie.rb +162 -18
- data/lib/skylight/sidekiq.rb +48 -0
- data/lib/skylight/subscriber.rb +110 -0
- data/lib/skylight/test.rb +146 -0
- data/lib/skylight/trace.rb +305 -10
- data/lib/skylight/user_config.rb +61 -0
- data/lib/skylight/util.rb +12 -0
- data/lib/skylight/util/allocation_free.rb +26 -0
- data/lib/skylight/util/clock.rb +56 -0
- data/lib/skylight/util/component.rb +5 -2
- data/lib/skylight/util/deploy.rb +7 -10
- data/lib/skylight/util/gzip.rb +20 -0
- data/lib/skylight/util/http.rb +5 -11
- data/lib/skylight/util/instrumenter_method.rb +26 -0
- data/lib/skylight/util/logging.rb +138 -0
- data/lib/skylight/util/lru_cache.rb +40 -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 +68 -0
- metadata +117 -19
data/lib/skylight/api.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "skylight/util/http"
|
|
|
4
4
|
module Skylight
|
|
5
5
|
# @api private
|
|
6
6
|
class Api
|
|
7
|
-
include
|
|
7
|
+
include Util::Logging
|
|
8
8
|
|
|
9
9
|
attr_reader :config
|
|
10
10
|
|
|
@@ -21,6 +21,7 @@ module Skylight
|
|
|
21
21
|
|
|
22
22
|
def errors
|
|
23
23
|
return unless res.respond_to?(:body) && res.body.is_a?(Hash)
|
|
24
|
+
|
|
24
25
|
res.body["errors"]
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -36,7 +37,7 @@ module Skylight
|
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
class ConfigValidationResults
|
|
39
|
-
include
|
|
40
|
+
include Util::Logging
|
|
40
41
|
|
|
41
42
|
attr_reader :raw_response
|
|
42
43
|
|
|
@@ -87,11 +88,13 @@ module Skylight
|
|
|
87
88
|
|
|
88
89
|
def validation_errors
|
|
89
90
|
return {} if config_valid? || !body
|
|
91
|
+
|
|
90
92
|
body["errors"]
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
def corrected_config
|
|
94
|
-
return
|
|
96
|
+
return nil if config_valid? || !body
|
|
97
|
+
|
|
95
98
|
body["corrected"]
|
|
96
99
|
end
|
|
97
100
|
end
|
|
@@ -107,6 +110,7 @@ module Skylight
|
|
|
107
110
|
res = http_request(:app_create, :post, params)
|
|
108
111
|
|
|
109
112
|
raise CreateFailed, res unless res.success?
|
|
113
|
+
|
|
110
114
|
res
|
|
111
115
|
end
|
|
112
116
|
|
data/lib/skylight/cli.rb
CHANGED
|
@@ -60,7 +60,7 @@ module Skylight
|
|
|
60
60
|
rescue Api::CreateFailed => e
|
|
61
61
|
say "Could not create the application. Please run `bundle exec skylight doctor` for diagnostics.", :red
|
|
62
62
|
say e.to_s, :yellow
|
|
63
|
-
rescue Interrupt
|
|
63
|
+
rescue Interrupt # rubocop:disable Lint/SuppressedException
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
desc "disable_dev_warning", "Disables warning about running Skylight in development mode for all local apps"
|
|
@@ -71,7 +71,8 @@ module Skylight
|
|
|
71
71
|
say "Development mode warning disabled", :green
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
desc "disable_env_warning", "Disables warning about running Skylight in environments not defined in
|
|
74
|
+
desc "disable_env_warning", "Disables warning about running Skylight in environments not defined in " \
|
|
75
|
+
"config.skylight.environments"
|
|
75
76
|
def disable_env_warning
|
|
76
77
|
user_config.disable_env_warning = true
|
|
77
78
|
user_config.save
|
|
@@ -93,7 +94,7 @@ module Skylight
|
|
|
93
94
|
begin
|
|
94
95
|
namefile = Tempfile.new("skylight-app-name")
|
|
95
96
|
# Windows appears to need double quotes for `rails runner`
|
|
96
|
-
`rails runner "File.open('#{namefile.path}', 'w') {|f| f.write(Rails.application.class.name) rescue '' }"`
|
|
97
|
+
`rails runner "File.open('#{namefile.path}', 'w') {|f| f.write(Rails.application.class.name) rescue '' }"` # rubocop:disable Layout/LineLength
|
|
97
98
|
name = namefile.read.split("::").first.underscore.titleize
|
|
98
99
|
name = nil if name.empty?
|
|
99
100
|
rescue => e
|
data/lib/skylight/cli/doctor.rb
CHANGED
|
@@ -24,7 +24,8 @@ module Skylight
|
|
|
24
24
|
say "Please update your certificates with RVM by running `rvm osx-ssl-certs update all`.", :yellow
|
|
25
25
|
say "Alternatively, try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your environment.", :yellow
|
|
26
26
|
else
|
|
27
|
-
say "Please update your local certificates or try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your
|
|
27
|
+
say "Please update your local certificates or try setting `SKYLIGHT_FORCE_OWN_CERTS=1` in your " \
|
|
28
|
+
"environment.", :yellow
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
else
|
|
@@ -84,20 +85,18 @@ module Skylight
|
|
|
84
85
|
say "Checking for valid configuration"
|
|
85
86
|
|
|
86
87
|
indent do
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
done!
|
|
88
|
+
config.validate!
|
|
89
|
+
say "Configuration is valid", :green
|
|
90
|
+
rescue ConfigError => e
|
|
91
|
+
encountered_error!
|
|
92
|
+
|
|
93
|
+
say "Configuration is invalid", :red
|
|
94
|
+
indent do
|
|
95
|
+
say e.message, :red
|
|
96
|
+
say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
|
|
100
97
|
end
|
|
98
|
+
|
|
99
|
+
done!
|
|
101
100
|
end
|
|
102
101
|
|
|
103
102
|
puts "\n"
|
data/lib/skylight/cli/merger.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Skylight
|
|
|
14
14
|
|
|
15
15
|
STRINGS = {
|
|
16
16
|
get_token: "get your merge token from `https://www.skylight.io/merging`",
|
|
17
|
-
unlisted:
|
|
17
|
+
unlisted: "My app isn't listed here :("
|
|
18
18
|
}.freeze
|
|
19
19
|
|
|
20
20
|
argument :merge_token, type: :string, desc: STRINGS[:get_token]
|
|
@@ -171,9 +171,9 @@ module Skylight
|
|
|
171
171
|
say "Merging..."
|
|
172
172
|
|
|
173
173
|
api.merge_apps!(@merge_token,
|
|
174
|
-
app_guid:
|
|
174
|
+
app_guid: @parent_app.guid,
|
|
175
175
|
component_guid: @child_app.guid,
|
|
176
|
-
environment:
|
|
176
|
+
environment: @child_env)
|
|
177
177
|
rescue => e
|
|
178
178
|
say("Something went wrong. Please contact support@skylight.io for more information.", :red)
|
|
179
179
|
done!(message: e.message, success: false)
|
|
@@ -252,7 +252,8 @@ module Skylight
|
|
|
252
252
|
|
|
253
253
|
def valid_component?(component_name, env)
|
|
254
254
|
return false unless env
|
|
255
|
-
|
|
255
|
+
|
|
256
|
+
Util::Component.new(env, component_name) && true
|
|
256
257
|
rescue ArgumentError
|
|
257
258
|
false
|
|
258
259
|
end
|
|
@@ -265,6 +266,7 @@ module Skylight
|
|
|
265
266
|
ret = Enumerator.new do |yielder|
|
|
266
267
|
@parents.each do |_, app|
|
|
267
268
|
next if app == @parent_app
|
|
269
|
+
|
|
268
270
|
app.components.each do |component|
|
|
269
271
|
yielder << OpenStruct.new({ app_name: app.name }.merge(component))
|
|
270
272
|
end
|
data/lib/skylight/config.rb
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
require "openssl"
|
|
2
|
+
require "yaml"
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "erb"
|
|
5
|
+
require "json"
|
|
6
|
+
require "skylight/util/logging"
|
|
7
|
+
require "skylight/util/proxy"
|
|
8
|
+
require "skylight/errors"
|
|
2
9
|
require "skylight/util/component"
|
|
3
10
|
require "skylight/util/deploy"
|
|
4
11
|
require "skylight/util/platform"
|
|
@@ -6,123 +13,185 @@ require "skylight/util/hostname"
|
|
|
6
13
|
require "skylight/util/ssl"
|
|
7
14
|
|
|
8
15
|
module Skylight
|
|
9
|
-
class Config
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
16
|
+
class Config
|
|
17
|
+
include Util::Logging
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
MUTEX = Mutex.new
|
|
21
|
+
|
|
22
|
+
# Map environment variable keys with Skylight configuration keys
|
|
23
|
+
ENV_TO_KEY = {
|
|
24
|
+
# == Authentication ==
|
|
25
|
+
-"AUTHENTICATION" => :authentication,
|
|
26
|
+
|
|
27
|
+
# == App settings ==
|
|
28
|
+
-"ROOT" => :root,
|
|
29
|
+
-"HOSTNAME" => :hostname,
|
|
30
|
+
-"SESSION_TOKEN" => :session_token,
|
|
31
|
+
|
|
32
|
+
# == Component settings ==
|
|
33
|
+
-"ENV" => :env,
|
|
34
|
+
-"COMPONENT" => :component,
|
|
35
|
+
-"REPORT_RAILS_ENV" => :report_rails_env,
|
|
36
|
+
|
|
37
|
+
# == Deploy settings ==
|
|
38
|
+
-"DEPLOY_ID" => :'deploy.id',
|
|
39
|
+
-"DEPLOY_GIT_SHA" => :'deploy.git_sha',
|
|
40
|
+
-"DEPLOY_DESCRIPTION" => :'deploy.description',
|
|
41
|
+
|
|
42
|
+
# == Logging ==
|
|
43
|
+
-"LOG_FILE" => :log_file,
|
|
44
|
+
-"LOG_LEVEL" => :log_level,
|
|
45
|
+
-"ALERT_LOG_FILE" => :alert_log_file,
|
|
46
|
+
-"NATIVE_LOG_FILE" => :native_log_file,
|
|
47
|
+
-"LOG_SQL_PARSE_ERRORS" => :log_sql_parse_errors,
|
|
48
|
+
|
|
49
|
+
# == Proxy ==
|
|
50
|
+
-"PROXY_URL" => :proxy_url,
|
|
51
|
+
|
|
52
|
+
# == Instrumenter ==
|
|
53
|
+
-"ENABLE_SEGMENTS" => :enable_segments,
|
|
54
|
+
-"ENABLE_SIDEKIQ" => :enable_sidekiq,
|
|
55
|
+
-"IGNORED_ENDPOINT" => :ignored_endpoint,
|
|
56
|
+
-"IGNORED_ENDPOINTS" => :ignored_endpoints,
|
|
57
|
+
-"SINATRA_ROUTE_PREFIXES" => :sinatra_route_prefixes,
|
|
58
|
+
-"ENABLE_SOURCE_LOCATIONS" => :enable_source_locations,
|
|
59
|
+
|
|
60
|
+
# == Max Span Handling ==
|
|
61
|
+
-"REPORT_MAX_SPANS_EXCEEDED" => :report_max_spans_exceeded,
|
|
62
|
+
-"PRUNE_LARGE_TRACES" => :prune_large_traces,
|
|
63
|
+
|
|
64
|
+
# == Skylight Remote ==
|
|
65
|
+
-"AUTH_URL" => :auth_url,
|
|
66
|
+
-"APP_CREATE_URL" => :app_create_url,
|
|
67
|
+
-"MERGES_URL" => :merges_url,
|
|
68
|
+
-"VALIDATION_URL" => :validation_url,
|
|
69
|
+
-"AUTH_HTTP_DEFLATE" => :auth_http_deflate,
|
|
70
|
+
-"AUTH_HTTP_CONNECT_TIMEOUT" => :auth_http_connect_timeout,
|
|
71
|
+
-"AUTH_HTTP_READ_TIMEOUT" => :auth_http_read_timeout,
|
|
72
|
+
-"REPORT_URL" => :report_url,
|
|
73
|
+
-"REPORT_HTTP_DEFLATE" => :report_http_deflate,
|
|
74
|
+
-"REPORT_HTTP_CONNECT_TIMEOUT" => :report_http_connect_timeout,
|
|
75
|
+
-"REPORT_HTTP_READ_TIMEOUT" => :report_http_read_timeout,
|
|
76
|
+
-"REPORT_HTTP_DISABLED" => :report_http_disabled,
|
|
77
|
+
|
|
78
|
+
# == Native agent settings ==
|
|
79
|
+
#
|
|
80
|
+
-"LAZY_START" => :'daemon.lazy_start',
|
|
81
|
+
-"DAEMON_EXEC_PATH" => :'daemon.exec_path',
|
|
82
|
+
-"DAEMON_LIB_PATH" => :'daemon.lib_path',
|
|
83
|
+
-"PIDFILE_PATH" => :'daemon.pidfile_path',
|
|
84
|
+
-"SOCKDIR_PATH" => :'daemon.sockdir_path',
|
|
85
|
+
-"BATCH_QUEUE_DEPTH" => :'daemon.batch_queue_depth',
|
|
86
|
+
-"BATCH_SAMPLE_SIZE" => :'daemon.batch_sample_size',
|
|
87
|
+
-"BATCH_FLUSH_INTERVAL" => :'daemon.batch_flush_interval',
|
|
88
|
+
-"DAEMON_TICK_INTERVAL" => :'daemon.tick_interval',
|
|
89
|
+
-"DAEMON_LOCK_CHECK_INTERVAL" => :'daemon.lock_check_interval',
|
|
90
|
+
-"DAEMON_INACTIVITY_TIMEOUT" => :'daemon.inactivity_timeout',
|
|
91
|
+
-"CLIENT_MAX_TRIES" => :'daemon.max_connect_tries',
|
|
92
|
+
-"CLIENT_CONN_TRY_WIN" => :'daemon.connect_try_window',
|
|
93
|
+
-"MAX_PRESPAWN_JITTER" => :'daemon.max_prespawn_jitter',
|
|
94
|
+
-"DAEMON_WAIT_TIMEOUT" => :'daemon.wait_timeout',
|
|
95
|
+
-"CLIENT_CHECK_INTERVAL" => :'daemon.client_check_interval',
|
|
96
|
+
-"CLIENT_QUEUE_DEPTH" => :'daemon.client_queue_depth',
|
|
97
|
+
-"CLIENT_WRITE_TIMEOUT" => :'daemon.client_write_timeout',
|
|
98
|
+
-"SSL_CERT_PATH" => :'daemon.ssl_cert_path',
|
|
99
|
+
-"SSL_CERT_DIR" => :'daemon.ssl_cert_dir',
|
|
100
|
+
|
|
101
|
+
# == Legacy env vars ==
|
|
102
|
+
#
|
|
103
|
+
-"AGENT_LOCKFILE" => :'agent.lockfile',
|
|
104
|
+
-"AGENT_SOCKFILE_PATH" => :'agent.sockfile_path',
|
|
105
|
+
|
|
106
|
+
# == User config settings ==
|
|
107
|
+
-"USER_CONFIG_PATH" => :user_config_path,
|
|
108
|
+
|
|
109
|
+
# == Heroku settings ==
|
|
110
|
+
-"HEROKU_DYNO_INFO_PATH" => :'heroku.dyno_info_path',
|
|
111
|
+
|
|
112
|
+
# == Source Location ==
|
|
113
|
+
-"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems
|
|
114
|
+
}.freeze
|
|
115
|
+
|
|
116
|
+
KEY_TO_NATIVE_ENV = {
|
|
117
|
+
# We use different log files for native and Ruby, but the native code doesn't know this
|
|
118
|
+
native_log_file: "LOG_FILE",
|
|
119
|
+
native_log_level: "LOG_LEVEL"
|
|
120
|
+
}.freeze
|
|
121
|
+
|
|
122
|
+
SERVER_VALIDATE = %i[].freeze
|
|
123
|
+
|
|
124
|
+
DEFAULT_IGNORED_SOURCE_LOCATION_GEMS = [
|
|
125
|
+
-"skylight",
|
|
126
|
+
-"activesupport",
|
|
127
|
+
-"activerecord"
|
|
128
|
+
].freeze
|
|
81
129
|
|
|
82
130
|
# Default values for Skylight configuration keys
|
|
83
131
|
def self.default_values
|
|
84
|
-
@default_values ||=
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
132
|
+
@default_values ||=
|
|
133
|
+
begin
|
|
134
|
+
ret = {
|
|
135
|
+
# URLs
|
|
136
|
+
auth_url: -"https://auth.skylight.io/agent",
|
|
137
|
+
app_create_url: -"https://www.skylight.io/apps",
|
|
138
|
+
merges_url: -"https://www.skylight.io/merges",
|
|
139
|
+
validation_url: -"https://auth.skylight.io/agent/config",
|
|
140
|
+
|
|
141
|
+
# Logging
|
|
142
|
+
log_file: -"-",
|
|
143
|
+
log_level: -"INFO",
|
|
144
|
+
alert_log_file: -"-",
|
|
145
|
+
log_sql_parse_errors: true,
|
|
146
|
+
|
|
147
|
+
# Features
|
|
148
|
+
enable_segments: true,
|
|
149
|
+
enable_sidekiq: false,
|
|
150
|
+
sinatra_route_prefixes: false,
|
|
151
|
+
enable_source_locations: true,
|
|
152
|
+
|
|
153
|
+
# Deploys
|
|
154
|
+
'heroku.dyno_info_path': -"/etc/heroku/dyno",
|
|
155
|
+
report_rails_env: true,
|
|
156
|
+
|
|
157
|
+
# Daemon
|
|
158
|
+
'daemon.lazy_start': true,
|
|
159
|
+
hostname: Util::Hostname.default_hostname,
|
|
160
|
+
report_max_spans_exceeded: false,
|
|
161
|
+
prune_large_traces: true
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
unless Util::Platform::OS == -"darwin"
|
|
165
|
+
ret[:'daemon.ssl_cert_path'] = Util::SSL.ca_cert_file_or_default
|
|
166
|
+
ret[:'daemon.ssl_cert_dir'] = Util::SSL.ca_cert_dir
|
|
167
|
+
end
|
|
96
168
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
ret[:'daemon.ssl_cert_dir'] = Util::SSL.ca_cert_dir
|
|
100
|
-
end
|
|
169
|
+
if Skylight.native?
|
|
170
|
+
native_path = Skylight.libskylight_path
|
|
101
171
|
|
|
102
|
-
|
|
103
|
-
|
|
172
|
+
ret[:'daemon.lib_path'] = native_path
|
|
173
|
+
ret[:'daemon.exec_path'] = File.join(native_path, "skylightd")
|
|
174
|
+
end
|
|
104
175
|
|
|
105
|
-
ret
|
|
106
|
-
ret[:'daemon.exec_path'] = File.join(native_path, "skylightd")
|
|
176
|
+
ret
|
|
107
177
|
end
|
|
108
|
-
|
|
109
|
-
ret
|
|
110
|
-
end
|
|
111
178
|
end
|
|
112
179
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
)
|
|
120
|
-
end
|
|
180
|
+
REQUIRED_KEYS = {
|
|
181
|
+
authentication: "authentication token",
|
|
182
|
+
hostname: "server hostname",
|
|
183
|
+
auth_url: "authentication url",
|
|
184
|
+
validation_url: "config validation url"
|
|
185
|
+
}.freeze
|
|
121
186
|
|
|
122
187
|
def self.native_env_keys
|
|
123
|
-
@native_env_keys ||=
|
|
188
|
+
@native_env_keys ||= %i[
|
|
189
|
+
native_log_level
|
|
190
|
+
native_log_file
|
|
191
|
+
log_sql_parse_errors
|
|
124
192
|
version
|
|
125
193
|
root
|
|
194
|
+
proxy_url
|
|
126
195
|
hostname
|
|
127
196
|
session_token
|
|
128
197
|
auth_url
|
|
@@ -143,7 +212,7 @@ module Skylight
|
|
|
143
212
|
daemon.batch_sample_size
|
|
144
213
|
daemon.batch_flush_interval
|
|
145
214
|
daemon.tick_interval
|
|
146
|
-
daemon.
|
|
215
|
+
daemon.lock_check_interval
|
|
147
216
|
daemon.inactivity_timeout
|
|
148
217
|
daemon.max_connect_tries
|
|
149
218
|
daemon.connect_try_window
|
|
@@ -157,27 +226,140 @@ module Skylight
|
|
|
157
226
|
]
|
|
158
227
|
end
|
|
159
228
|
|
|
229
|
+
# Maps legacy config keys to new config keys
|
|
160
230
|
def self.legacy_keys
|
|
161
|
-
@legacy_keys ||=
|
|
231
|
+
@legacy_keys ||= {
|
|
162
232
|
'agent.sockfile_path': :'daemon.sockdir_path',
|
|
163
233
|
'agent.lockfile': :'daemon.pidfile_path'
|
|
164
|
-
|
|
234
|
+
}
|
|
165
235
|
end
|
|
166
236
|
|
|
167
237
|
def self.validators
|
|
168
|
-
@validators ||=
|
|
238
|
+
@validators ||= {
|
|
169
239
|
'agent.interval': [->(v, _c) { v.is_a?(Integer) && v > 0 }, "must be an integer greater than 0"]
|
|
170
|
-
|
|
240
|
+
}
|
|
171
241
|
end
|
|
172
242
|
|
|
173
243
|
# @api private
|
|
174
|
-
|
|
175
|
-
|
|
244
|
+
attr_reader :priority_key
|
|
245
|
+
|
|
246
|
+
# @api private
|
|
247
|
+
def initialize(*args)
|
|
248
|
+
attrs = {}
|
|
249
|
+
|
|
250
|
+
if args.last.is_a?(Hash)
|
|
251
|
+
attrs = args.pop.dup
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
@values = {}
|
|
255
|
+
@priority = {}
|
|
256
|
+
@priority_regexp = nil
|
|
257
|
+
@alert_logger = nil
|
|
258
|
+
@logger = nil
|
|
259
|
+
|
|
260
|
+
p = attrs.delete(:priority)
|
|
261
|
+
|
|
262
|
+
if (@priority_key = args[0])
|
|
263
|
+
@priority_regexp = /^#{Regexp.escape(priority_key)}\.(.+)$/
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
attrs.each do |k, v|
|
|
267
|
+
self[k] = v
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
p&.each do |k, v|
|
|
271
|
+
@priority[self.class.remap_key(k)] = v
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def self.load(opts = {}, env = ENV)
|
|
276
|
+
attrs = {}
|
|
277
|
+
path = opts.delete(:file)
|
|
278
|
+
priority_key = opts.delete(:priority_key)
|
|
279
|
+
priority_key ||= opts[:env] # if a priority_key is not given, use env if available
|
|
280
|
+
|
|
281
|
+
if path
|
|
282
|
+
error = nil
|
|
283
|
+
begin
|
|
284
|
+
attrs = YAML.safe_load(ERB.new(File.read(path)).result,
|
|
285
|
+
[], # permitted_classes
|
|
286
|
+
[], # permitted_symbols
|
|
287
|
+
true) # aliases enabled
|
|
288
|
+
error = "empty file" unless attrs
|
|
289
|
+
error = "invalid format" if attrs && !attrs.is_a?(Hash)
|
|
290
|
+
rescue Exception => e
|
|
291
|
+
error = e.message
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
raise ConfigError, "could not load config file; msg=#{error}" if error
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# The key-value pairs in this `priority` option are inserted into the
|
|
298
|
+
# config's @priority hash *after* anything listed under priority_key;
|
|
299
|
+
# i.e., ENV takes precendence over priority_key
|
|
300
|
+
if env
|
|
301
|
+
attrs[:priority] = remap_env(env)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
config = new(priority_key, attrs)
|
|
305
|
+
|
|
306
|
+
opts.each do |k, v|
|
|
307
|
+
config[k] = v
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
config
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def self.remap_key(key)
|
|
314
|
+
key = key.to_sym
|
|
315
|
+
legacy_keys[key] || key
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# @api private
|
|
319
|
+
def self.remap_env(env)
|
|
320
|
+
ret = {}
|
|
321
|
+
|
|
322
|
+
return ret unless env
|
|
323
|
+
|
|
324
|
+
# Only set if it exists, we don't want to set to a nil value
|
|
325
|
+
if (proxy_url = Util::Proxy.detect_url(env))
|
|
326
|
+
ret[:proxy_url] = proxy_url
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
env.each do |k, val|
|
|
330
|
+
next unless k =~ /^(?:SK|SKYLIGHT)_(.+)$/
|
|
331
|
+
next unless (key = ENV_TO_KEY[$1])
|
|
332
|
+
|
|
333
|
+
ret[key] =
|
|
334
|
+
case val
|
|
335
|
+
when /^false$/i then false
|
|
336
|
+
when /^true$/i then true
|
|
337
|
+
when /^(nil|null)$/i then nil
|
|
338
|
+
when /^\d+$/ then val.to_i
|
|
339
|
+
when /^\d+\.\d+$/ then val.to_f
|
|
340
|
+
else val
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
ret
|
|
176
345
|
end
|
|
177
346
|
|
|
178
347
|
# @api private
|
|
179
348
|
def validate!
|
|
180
|
-
|
|
349
|
+
REQUIRED_KEYS.each do |k, v|
|
|
350
|
+
unless get(k)
|
|
351
|
+
raise ConfigError, "#{v} required"
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
log_file = self[:log_file]
|
|
356
|
+
alert_log_file = self[:alert_log_file]
|
|
357
|
+
native_log_file = self.native_log_file
|
|
358
|
+
|
|
359
|
+
check_logfile_permissions(log_file, "log_file")
|
|
360
|
+
check_logfile_permissions(alert_log_file, "alert_log_file")
|
|
361
|
+
# TODO: Support rotation interpolation in this check
|
|
362
|
+
check_logfile_permissions(native_log_file, "native_log_file")
|
|
181
363
|
|
|
182
364
|
# TODO: Move this out of the validate! method: https://github.com/tildeio/direwolf-agent/issues/273
|
|
183
365
|
# FIXME: Why not set the sockdir_path and pidfile_path explicitly?
|
|
@@ -191,6 +373,300 @@ module Skylight
|
|
|
191
373
|
true
|
|
192
374
|
end
|
|
193
375
|
|
|
376
|
+
def check_file_permissions(file, key)
|
|
377
|
+
file_root = File.dirname(file)
|
|
378
|
+
|
|
379
|
+
# Try to make the directory, don't blow up if we can't. Our writable? check will fail later.
|
|
380
|
+
FileUtils.mkdir_p file_root rescue nil
|
|
381
|
+
|
|
382
|
+
if File.exist?(file) && !FileTest.writable?(file)
|
|
383
|
+
raise ConfigError, "File `#{file}` is not writable. Please set #{key} in your config to a writable path"
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
unless FileTest.writable?(file_root)
|
|
387
|
+
raise ConfigError, "Directory `#{file_root}` is not writable. Please set #{key} in your config to a " \
|
|
388
|
+
"writable path"
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def check_logfile_permissions(log_file, key)
|
|
393
|
+
return if log_file == "-" # STDOUT
|
|
394
|
+
|
|
395
|
+
log_file = File.expand_path(log_file, root)
|
|
396
|
+
check_file_permissions(log_file, key)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def key?(key)
|
|
400
|
+
key = self.class.remap_key(key)
|
|
401
|
+
@priority.key?(key) || @values.key?(key)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def get(key, default = nil)
|
|
405
|
+
key = self.class.remap_key(key)
|
|
406
|
+
|
|
407
|
+
return @priority[key] if @priority.key?(key)
|
|
408
|
+
return @values[key] if @values.key?(key)
|
|
409
|
+
return self.class.default_values[key] if self.class.default_values.key?(key)
|
|
410
|
+
|
|
411
|
+
if default
|
|
412
|
+
return default
|
|
413
|
+
elsif block_given?
|
|
414
|
+
return yield key
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
nil
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
alias [] get
|
|
421
|
+
|
|
422
|
+
def set(key, val, scope = nil)
|
|
423
|
+
if scope
|
|
424
|
+
key = [scope, key].join(".")
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
if val.is_a?(Hash)
|
|
428
|
+
val.each do |k, v|
|
|
429
|
+
set(k, v, key)
|
|
430
|
+
end
|
|
431
|
+
else
|
|
432
|
+
k = self.class.remap_key(key)
|
|
433
|
+
|
|
434
|
+
if (validator = self.class.validators[k])
|
|
435
|
+
blk, msg = validator
|
|
436
|
+
|
|
437
|
+
unless blk.call(val, self)
|
|
438
|
+
error_msg = "invalid value for #{k} (#{val})"
|
|
439
|
+
error_msg << ", #{msg}" if msg
|
|
440
|
+
raise ConfigError, error_msg
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
if @priority_regexp && k =~ @priority_regexp
|
|
445
|
+
@priority[$1.to_sym] = val
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
@values[k] = val
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
alias []= set
|
|
453
|
+
|
|
454
|
+
def send_or_get(val)
|
|
455
|
+
respond_to?(val) ? send(val) : get(val)
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def duration_ms(key, default = nil)
|
|
459
|
+
if (v = self[key]) && v.to_s =~ /^\s*(\d+)(s|sec|ms|micros|nanos)?\s*$/
|
|
460
|
+
v = $1.to_i
|
|
461
|
+
case $2
|
|
462
|
+
when "ms"
|
|
463
|
+
v
|
|
464
|
+
when "micros"
|
|
465
|
+
v / 1_000
|
|
466
|
+
when "nanos"
|
|
467
|
+
v / 1_000_000
|
|
468
|
+
else # "s", "sec", nil
|
|
469
|
+
v * 1000
|
|
470
|
+
end
|
|
471
|
+
else
|
|
472
|
+
default
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def to_native_env
|
|
477
|
+
ret = []
|
|
478
|
+
|
|
479
|
+
self.class.native_env_keys.each do |key|
|
|
480
|
+
value = send_or_get(key)
|
|
481
|
+
unless value.nil?
|
|
482
|
+
env_key = KEY_TO_NATIVE_ENV[key] || ENV_TO_KEY.key(key) || key.upcase
|
|
483
|
+
ret << "SKYLIGHT_#{env_key}" << cast_for_env(value)
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
ret << "SKYLIGHT_AUTHENTICATION" << authentication_with_meta
|
|
488
|
+
ret << "SKYLIGHT_VALIDATE_AUTHENTICATION" << "false"
|
|
489
|
+
|
|
490
|
+
ret
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
#
|
|
494
|
+
#
|
|
495
|
+
# ===== Helpers =====
|
|
496
|
+
#
|
|
497
|
+
#
|
|
498
|
+
|
|
499
|
+
def version
|
|
500
|
+
VERSION
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
# @api private
|
|
504
|
+
def gc
|
|
505
|
+
@gc ||= GC.new(self, get("gc.profiler", VM::GC.new))
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# @api private
|
|
509
|
+
def ignored_endpoints
|
|
510
|
+
@ignored_endpoints ||=
|
|
511
|
+
begin
|
|
512
|
+
ignored_endpoints = get(:ignored_endpoints)
|
|
513
|
+
|
|
514
|
+
# If, for some odd reason you have a comma in your endpoint name, use the
|
|
515
|
+
# YML config instead.
|
|
516
|
+
if ignored_endpoints.is_a?(String)
|
|
517
|
+
ignored_endpoints = ignored_endpoints.split(/\s*,\s*/)
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
val = Array(get(:ignored_endpoint))
|
|
521
|
+
val.concat(Array(ignored_endpoints))
|
|
522
|
+
val
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# @api private
|
|
527
|
+
def source_location_ignored_gems
|
|
528
|
+
@source_location_ignored_gems ||=
|
|
529
|
+
begin
|
|
530
|
+
ignored_gems = get(:source_location_ignored_gems)
|
|
531
|
+
if ignored_gems.is_a?(String)
|
|
532
|
+
ignored_gems = ignored_gems.split(/\s*,\s*/)
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
Array(ignored_gems) | DEFAULT_IGNORED_SOURCE_LOCATION_GEMS
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
def root
|
|
540
|
+
@root ||= Pathname.new(self[:root] || Dir.pwd).realpath
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def log_level
|
|
544
|
+
@log_level ||=
|
|
545
|
+
if trace?
|
|
546
|
+
Logger::DEBUG
|
|
547
|
+
else
|
|
548
|
+
case get(:log_level)
|
|
549
|
+
when /^debug$/i then Logger::DEBUG
|
|
550
|
+
when /^info$/i then Logger::INFO
|
|
551
|
+
when /^warn$/i then Logger::WARN
|
|
552
|
+
when /^error$/i then Logger::ERROR
|
|
553
|
+
when /^fatal$/i then Logger::FATAL
|
|
554
|
+
else Logger::ERROR
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def native_log_level
|
|
560
|
+
@native_log_level ||=
|
|
561
|
+
if trace?
|
|
562
|
+
"trace"
|
|
563
|
+
else
|
|
564
|
+
case log_level
|
|
565
|
+
when Logger::DEBUG then "debug"
|
|
566
|
+
when Logger::INFO then "info"
|
|
567
|
+
when Logger::WARN then "warn"
|
|
568
|
+
else "error"
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
def logger
|
|
574
|
+
@logger ||=
|
|
575
|
+
MUTEX.synchronize do
|
|
576
|
+
load_logger
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def native_log_file
|
|
581
|
+
@native_log_file ||= get("native_log_file") do
|
|
582
|
+
log_file = self["log_file"]
|
|
583
|
+
return "-" if log_file == "-"
|
|
584
|
+
|
|
585
|
+
parts = log_file.to_s.split(".")
|
|
586
|
+
parts.insert(-2, "native")
|
|
587
|
+
parts.join(".")
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
attr_writer :logger, :alert_logger
|
|
592
|
+
|
|
593
|
+
def alert_logger
|
|
594
|
+
@alert_logger ||= MUTEX.synchronize do
|
|
595
|
+
unless (l = @alert_logger)
|
|
596
|
+
out = get(:alert_log_file)
|
|
597
|
+
out = Util::AlertLogger.new(load_logger) if out == "-"
|
|
598
|
+
|
|
599
|
+
l = create_logger(out, level: Logger::DEBUG)
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
l
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def enable_segments?
|
|
607
|
+
!!get(:enable_segments)
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def enable_sidekiq?
|
|
611
|
+
!!get(:enable_sidekiq)
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
def sinatra_route_prefixes?
|
|
615
|
+
!!get(:sinatra_route_prefixes)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
def enable_source_locations?
|
|
619
|
+
!!get(:enable_source_locations)
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
def user_config
|
|
623
|
+
@user_config ||= UserConfig.new(self)
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
def on_heroku?
|
|
627
|
+
File.exist?(get(:'heroku.dyno_info_path'))
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
private
|
|
631
|
+
|
|
632
|
+
def create_logger(out, level: :info)
|
|
633
|
+
if out.is_a?(String)
|
|
634
|
+
out = File.expand_path(out, root)
|
|
635
|
+
# May be redundant since we also do this in the permissions check
|
|
636
|
+
FileUtils.mkdir_p(File.dirname(out))
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
Logger.new(out, progname: "Skylight", level: level)
|
|
640
|
+
rescue
|
|
641
|
+
Logger.new($stdout, progname: "Skylight", level: level)
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
def load_logger
|
|
645
|
+
unless (l = @logger)
|
|
646
|
+
out = get(:log_file)
|
|
647
|
+
out = $stdout if out == "-"
|
|
648
|
+
l = create_logger(out, level: log_level)
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
l
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
def cast_for_env(val)
|
|
655
|
+
case val
|
|
656
|
+
when true then "true"
|
|
657
|
+
when false then "false"
|
|
658
|
+
when nil then "nil"
|
|
659
|
+
else val.to_s
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
public
|
|
664
|
+
|
|
665
|
+
# @api private
|
|
666
|
+
def api
|
|
667
|
+
@api ||= Api.new(self)
|
|
668
|
+
end
|
|
669
|
+
|
|
194
670
|
def validate_with_server
|
|
195
671
|
res = api.validate_config
|
|
196
672
|
|
|
@@ -212,6 +688,10 @@ module Skylight
|
|
|
212
688
|
return false if res.forbidden?
|
|
213
689
|
|
|
214
690
|
corrected_config = res.corrected_config
|
|
691
|
+
|
|
692
|
+
# Use defaults if no corrected config is available. This will happen if the request failed.
|
|
693
|
+
corrected_config ||= Hash[SERVER_VALIDATE.map { |k| [k, self.class.default_values.fetch(k)] }]
|
|
694
|
+
|
|
215
695
|
config_to_update = corrected_config.reject { |k, v| get(k) == v }
|
|
216
696
|
unless config_to_update.empty?
|
|
217
697
|
info("Updating config values:")
|
|
@@ -220,7 +700,7 @@ module Skylight
|
|
|
220
700
|
|
|
221
701
|
# This is a weird way to handle priorities
|
|
222
702
|
# See https://github.com/tildeio/direwolf-agent/issues/275
|
|
223
|
-
k = "#{
|
|
703
|
+
k = "#{priority_key}.#{k}" if priority_key
|
|
224
704
|
|
|
225
705
|
set(k, v)
|
|
226
706
|
end
|
|
@@ -235,23 +715,16 @@ module Skylight
|
|
|
235
715
|
FileUtils.mkdir_p sockdir_path rescue nil
|
|
236
716
|
|
|
237
717
|
unless FileTest.writable?(sockdir_path)
|
|
238
|
-
raise
|
|
718
|
+
raise ConfigError, "Directory `#{sockdir_path}` is not writable. Please set daemon.sockdir_path in " \
|
|
719
|
+
"your config to a writable path"
|
|
239
720
|
end
|
|
240
721
|
|
|
241
722
|
if check_nfs(sockdir_path)
|
|
242
|
-
raise
|
|
723
|
+
raise ConfigError, "Directory `#{sockdir_path}` is an NFS mount and will not allow sockets. Please set " \
|
|
724
|
+
"daemon.sockdir_path in your config to a non-NFS path."
|
|
243
725
|
end
|
|
244
726
|
end
|
|
245
727
|
|
|
246
|
-
def to_native_env
|
|
247
|
-
ret = super
|
|
248
|
-
|
|
249
|
-
ret << "SKYLIGHT_AUTHENTICATION" << authentication_with_meta
|
|
250
|
-
ret << "SKYLIGHT_VALIDATE_AUTHENTICATION" << "false"
|
|
251
|
-
|
|
252
|
-
ret
|
|
253
|
-
end
|
|
254
|
-
|
|
255
728
|
def write(path)
|
|
256
729
|
FileUtils.mkdir_p(File.dirname(path))
|
|
257
730
|
|
|
@@ -292,7 +765,7 @@ module Skylight
|
|
|
292
765
|
|
|
293
766
|
def components
|
|
294
767
|
@components ||= {
|
|
295
|
-
web:
|
|
768
|
+
web: Util::Component.new(
|
|
296
769
|
get(:env),
|
|
297
770
|
Util::Component::DEFAULT_NAME
|
|
298
771
|
),
|
|
@@ -303,18 +776,22 @@ module Skylight
|
|
|
303
776
|
)
|
|
304
777
|
}
|
|
305
778
|
rescue ArgumentError => e
|
|
306
|
-
raise
|
|
779
|
+
raise ConfigError, e.message
|
|
307
780
|
end
|
|
308
781
|
|
|
309
782
|
def component
|
|
310
783
|
components[:web]
|
|
311
784
|
end
|
|
312
785
|
|
|
786
|
+
def to_json(*)
|
|
787
|
+
JSON.generate(as_json)
|
|
788
|
+
end
|
|
789
|
+
|
|
313
790
|
def as_json(*)
|
|
314
791
|
{
|
|
315
792
|
config: {
|
|
316
793
|
priority: @priority.merge(component.as_json),
|
|
317
|
-
values:
|
|
794
|
+
values: @values
|
|
318
795
|
}
|
|
319
796
|
}
|
|
320
797
|
end
|