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