class Skylight::Core::Config
Constants
- MUTEX
@api private
Attributes
alert_logger[W]
environment[R]
@api private
logger[W]
Public Class Methods
default_values()
click to toggle source
Default values for Skylight
configuration keys
# File lib/skylight/core/config.rb, line 50 def self.default_values { log_file: "-".freeze, log_level: "INFO".freeze, alert_log_file: "-".freeze, log_sql_parse_errors: true, enable_segments: true, enable_sidekiq: false, sinatra_route_prefixes: false, 'heroku.dyno_info_path': "/etc/heroku/dyno" } end
env_matcher()
click to toggle source
# File lib/skylight/core/config.rb, line 20 def self.env_matcher; /^(?:SK|SKYLIGHT)_(.+)$/ end
env_prefix()
click to toggle source
# File lib/skylight/core/config.rb, line 21 def self.env_prefix; "SKYLIGHT_" end
env_to_key()
click to toggle source
Map environment variable keys with Skylight
configuration keys
# File lib/skylight/core/config.rb, line 25 def self.env_to_key { # == Logging == "LOG_FILE" => :log_file, "LOG_LEVEL" => :log_level, "ALERT_LOG_FILE" => :alert_log_file, "LOG_SQL_PARSE_ERRORS" => :log_sql_parse_errors, # == Proxy == "PROXY_URL" => :proxy_url, # == Instrumenter == "ENABLE_SEGMENTS" => :enable_segments, "ENABLE_SIDEKIQ" => :enable_sidekiq, "SINATRA_ROUTE_PREFIXES" => :sinatra_route_prefixes, # == User config settings == "USER_CONFIG_PATH" => :user_config_path, # == Heroku settings == "HEROKU_DYNO_INFO_PATH" => :'heroku.dyno_info_path' } end
legacy_keys()
click to toggle source
Maps legacy config keys to new config keys
# File lib/skylight/core/config.rb, line 83 def self.legacy_keys # No legacy keys for now {} end
load(opts = {}, env = ENV)
click to toggle source
# File lib/skylight/core/config.rb, line 127 def self.load(opts = {}, env = ENV) attrs = {} path = opts.delete(:file) environment = opts.delete(:environment) if path error = nil begin attrs = YAML.safe_load(ERB.new(File.read(path)).result, [], # permitted_classes [], # permitted_symbols true # aliases enabled ) error = "empty file" unless attrs error = "invalid format" if attrs && !attrs.is_a?(Hash) rescue Exception => e error = e.message end raise ConfigError, "could not load config file; msg=#{error}" if error end if env attrs[:priority] = remap_env(env) end config = new(environment, attrs) opts.each do |k, v| config[k] = v end config end
log_name()
click to toggle source
rubocop:disable Style/SingleLineMethods, Layout/EmptyLineBetweenDefs
# File lib/skylight/core/config.rb, line 17 def self.log_name; "Skylight" end
native_env_keys()
click to toggle source
# File lib/skylight/core/config.rb, line 74 def self.native_env_keys %i[ version root proxy_url ] end
new(*args)
click to toggle source
@api private
# File lib/skylight/core/config.rb, line 97 def initialize(*args) attrs = {} if args.last.is_a?(Hash) attrs = args.pop.dup end @values = {} @priority = {} @regexp = nil @alert_logger = nil @logger = nil p = attrs.delete(:priority) if (@environment = args[0]) @regexp = /^#{Regexp.escape(@environment)}\.(.+)$/ end attrs.each do |k, v| self[k] = v end if p p.each do |k, v| @priority[self.class.remap_key(k)] = v end end end
remap_env(env)
click to toggle source
@api private
# File lib/skylight/core/config.rb, line 168 def self.remap_env(env) ret = {} return ret unless env # Only set if it exists, we don't want to set to a nil value if (proxy_url = Util::Proxy.detect_url(env)) ret[:proxy_url] = proxy_url end env.each do |k, val| next unless k =~ env_matcher next unless (key = env_to_key[$1]) ret[key] = case val when /^false$/i then false when /^true$/i then true when /^(nil|null)$/i then nil when /^\d+$/ then val.to_i when /^\d+\.\d+$/ then val.to_f else val end end ret end
remap_key(key)
click to toggle source
# File lib/skylight/core/config.rb, line 162 def self.remap_key(key) key = key.to_sym legacy_keys[key] || key end
required_keys()
click to toggle source
# File lib/skylight/core/config.rb, line 63 def self.required_keys # Nothing is required in this base class. {} end
server_validated_keys()
click to toggle source
# File lib/skylight/core/config.rb, line 68 def self.server_validated_keys # Nothing is validated for now, but this is a list of symbols # for the key we want to validate. [] end
service_name()
click to toggle source
# File lib/skylight/core/config.rb, line 18 def self.service_name; log_name end
support_email()
click to toggle source
# File lib/skylight/core/config.rb, line 19 def self.support_email; "support@skylight.io" end
validators()
click to toggle source
# File lib/skylight/core/config.rb, line 88 def self.validators # None for now {} end
Public Instance Methods
alert_logger()
click to toggle source
# File lib/skylight/core/config.rb, line 392 def alert_logger @alert_logger ||= MUTEX.synchronize do unless (l = @alert_logger) out = get(:alert_log_file) out = Util::AlertLogger.new(load_logger) if out == "-" l = create_logger(out) l.level = Logger::DEBUG end l end end
as_json(*)
click to toggle source
# File lib/skylight/core/config.rb, line 319 def as_json(*) { config: { priority: @priority, values: @values } } end
check_file_permissions(file, key)
click to toggle source
# File lib/skylight/core/config.rb, line 217 def check_file_permissions(file, key) file_root = File.dirname(file) # Try to make the directory, don't blow up if we can't. Our writable? check will fail later. FileUtils.mkdir_p file_root rescue nil if File.exist?(file) && !FileTest.writable?(file) raise ConfigError, "File `#{file}` is not writable. Please set #{key} in your config to a writable path" end unless FileTest.writable?(file_root) raise ConfigError, "Directory `#{file_root}` is not writable. Please set #{key} in your config to a writable path" end end
check_logfile_permissions(log_file, key)
click to toggle source
# File lib/skylight/core/config.rb, line 232 def check_logfile_permissions(log_file, key) return if log_file == "-" # STDOUT log_file = File.expand_path(log_file, root) check_file_permissions(log_file, key) end
duration_ms(key, default = nil)
click to toggle source
# File lib/skylight/core/config.rb, line 297 def duration_ms(key, default = nil) if (v = self[key]) && v.to_s =~ /^\s*(\d+)(s|sec|ms|micros|nanos)?\s*$/ v = $1.to_i case $2 when "ms" v when "micros" v / 1_000 when "nanos" v / 1_000_000 else # "s", "sec", nil v * 1000 end else default end end
enable_segments?()
click to toggle source
# File lib/skylight/core/config.rb, line 408 def enable_segments? !!get(:enable_segments) end
enable_sidekiq?()
click to toggle source
# File lib/skylight/core/config.rb, line 412 def enable_sidekiq? !!get(:enable_sidekiq) end
gc()
click to toggle source
@api private
# File lib/skylight/core/config.rb, line 357 def gc @gc ||= GC.new(self, get("gc.profiler", VM::GC.new)) end
get(key, default = nil) { |key| ... }
click to toggle source
# File lib/skylight/core/config.rb, line 243 def get(key, default = nil) key = self.class.remap_key(key) return @priority[key] if @priority.key?(key) return @values[key] if @values.key?(key) return self.class.default_values[key] if self.class.default_values.key?(key) if default return default elsif block_given? return yield key end nil end
Also aliased as: []
ignored_endpoints()
click to toggle source
@api private
# File lib/skylight/core/config.rb, line 362 def ignored_endpoints @ignored_endpoints ||= begin ignored_endpoints = get(:ignored_endpoints) # If, for some odd reason you have a comma in your endpoint name, use the # YML config instead. if ignored_endpoints.is_a?(String) ignored_endpoints = ignored_endpoints.split(/\s*,\s*/) end val = Array(get(:ignored_endpoint)) val.concat(Array(ignored_endpoints)) val end end
key?(key)
click to toggle source
# File lib/skylight/core/config.rb, line 238 def key?(key) key = self.class.remap_key(key) @priority.key?(key) || @values.key?(key) end
logger()
click to toggle source
# File lib/skylight/core/config.rb, line 383 def logger @logger ||= MUTEX.synchronize do load_logger end end
on_heroku?()
click to toggle source
# File lib/skylight/core/config.rb, line 424 def on_heroku? File.exist?(get(:'heroku.dyno_info_path')) end
root()
click to toggle source
# File lib/skylight/core/config.rb, line 379 def root self[:root] || Dir.pwd end
send_or_get(val)
click to toggle source
# File lib/skylight/core/config.rb, line 293 def send_or_get(val) respond_to?(val) ? send(val) : get(val) end
set(key, val, scope = nil)
click to toggle source
# File lib/skylight/core/config.rb, line 261 def set(key, val, scope = nil) if scope key = [scope, key].join(".") end if val.is_a?(Hash) val.each do |k, v| set(k, v, key) end else k = self.class.remap_key(key) if (validator = self.class.validators[k]) blk, msg = validator unless blk.call(val, self) error_msg = "invalid value for #{k} (#{val})" error_msg << ", #{msg}" if msg raise ConfigError, error_msg end end if @regexp && k =~ @regexp @priority[$1.to_sym] = val end @values[k] = val end end
Also aliased as: []=
sinatra_route_prefixes?()
click to toggle source
# File lib/skylight/core/config.rb, line 416 def sinatra_route_prefixes? !!get(:sinatra_route_prefixes) end
to_json(*)
click to toggle source
# File lib/skylight/core/config.rb, line 315 def to_json(*) JSON.generate(as_json) end
to_native_env()
click to toggle source
# File lib/skylight/core/config.rb, line 328 def to_native_env ret = [] self.class.native_env_keys.each do |key| value = send_or_get(key) unless value.nil? env_key = self.class.env_to_key.key(key) || key.upcase ret << "#{self.class.env_prefix}#{env_key}" << cast_for_env(value) end end ret end
user_config()
click to toggle source
# File lib/skylight/core/config.rb, line 420 def user_config @user_config ||= UserConfig.new(self) end
validate!()
click to toggle source
@api private
# File lib/skylight/core/config.rb, line 197 def validate! self.class.required_keys.each do |k, v| unless get(k) raise ConfigError, "#{v} required" end end log_file = self[:log_file] alert_log_file = self[:alert_log_file] check_logfile_permissions(log_file, "log_file") check_logfile_permissions(alert_log_file, "alert_log_file") true end
validate_with_server()
click to toggle source
# File lib/skylight/core/config.rb, line 213 def validate_with_server true end
version()
click to toggle source
write(_path)
click to toggle source
# File lib/skylight/core/config.rb, line 342 def write(_path) raise "not implemented" end
Private Instance Methods
cast_for_env(val)
click to toggle source
# File lib/skylight/core/config.rb, line 470 def cast_for_env(val) case val when true then "true" when false then "false" when nil then "nil" else val.to_s end end
create_logger(out)
click to toggle source
# File lib/skylight/core/config.rb, line 430 def create_logger(out) l = begin if out.is_a?(String) out = File.expand_path(out, root) # May be redundant since we also do this in the permissions check FileUtils.mkdir_p(File.dirname(out)) end Logger.new(out) rescue Logger.new(STDOUT) end l.progname = self.class.log_name l end
load_logger()
click to toggle source
# File lib/skylight/core/config.rb, line 446 def load_logger unless (l = @logger) out = get(:log_file) out = STDOUT if out == "-" l = create_logger(out) l.level = if trace? Logger::DEBUG else case get(:log_level) when /^debug$/i then Logger::DEBUG when /^info$/i then Logger::INFO when /^warn$/i then Logger::WARN when /^error$/i then Logger::ERROR when /^fatal$/i then Logger::FATAL else Logger::ERROR end end end l end