class StackifyRubyAPM::Config

@api private

Constants

DEFAULTS
ENV_TO_KEY

Attributes

agent_traces_url[RW]
already_instrumented_flag[RW]
apm_disabled_in_rake[R]
application_name[RW]
check_trace_log_per_hour[RW]
client_id[R]
client_run_domain[R]
config_file[RW]
debug_logging[RW]
debug_transactions[RW]
debugger_byte_size[RW]
debugger_filenum_rotate[RW]
delay_seconds[RW]
device_id[R]
disabled_spies[RW]
enabled_environments[RW]
environment_name[RW]
filenum_rotate[RW]
filter_exception_types[RW]
flush_interval_seconds[RW]
hostname[RW]
http_status[RW]
instrument[RW]
json_config_file[RW]
lambda_handler[RW]
log_level[RW]
log_path[RW]
log_trace_path[RW]
logger[RW]
logger_byte_size[RW]
logtime_created[RW]
max_queue_size[RW]
max_retries[RW]
prefix_enabled[RW]
queue[RW]
root_path[RW]
rum_auto_injection[RW]
rum_enabled[RW]
rum_script_injected[RW]
rum_script_src[RW]
source_lines_error_app_frames[RW]
source_lines_error_library_frames[RW]
source_lines_span_app_frames[RW]
source_lines_span_library_frames[RW]
span_frames_min_duration[RW]
stackify_properties_file[RW]
trace_log_age_in_hour[RW]
tracer_logger[RW]
transport[RW]
transport_http_endpoint[RW]
unix_socket_path[RW]
view_paths[RW]

Public Class Methods

new(options = {}) { |self| ... } click to toggle source
# File lib/stackify_apm/config.rb, line 105
def initialize(options = {})
  set_defaults
  set_from_args(options)
  set_from_config_file
  set_from_env
  set_prefix_paths if @prefix_enabled
  yield self if block_given?
  debug_logger
  StackifyRubyAPM::Util.host_os == 'WINDOWS' ? load_stackify_props_windows : load_stackify_props_linux
  validate_apm_yml
end

Public Instance Methods

app=(app) click to toggle source
# File lib/stackify_apm/config.rb, line 183
def app=(app)
  case app_type?(app)
  when :rails
    set_rails(app)
  else
    # TODO: define custom?
    self.application_name = 'ruby'
  end
end
app_type?(app) click to toggle source
# File lib/stackify_apm/config.rb, line 193
def app_type?(app)
  return :rails if defined?(::Rails) && app.is_a?(Rails::Application)

  nil
end
available_spies() click to toggle source

available spies to use when framework is rails

# File lib/stackify_apm/config.rb, line 200
def available_spies
  %w[
    action_dispatch
    mongo
    net_http
    custom_instrumenter
    httpclient
    redis
    sequel
    tilt
    httprb
    curb
    curb/easy
    curb/multi
    httparty
    stackify_logger
    sidekiq
    delayed_job 
    faraday
    sucker_punch
    dynamo_db
  ]
end
debug_logger() click to toggle source

Default Transport

initialize default logger transport

# File lib/stackify_apm/config.rb, line 259
def debug_logger
  case @transport.downcase
  # For unix socket we don't create a trace log file
  when StackifyRubyAPM::TRACE_LOG
    debugger_logpath = log_path == '-' ? $stdout : log_path
    logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
    logger.level = log_level
    self.logger = logger
  end
end
enabled_spies() click to toggle source
# File lib/stackify_apm/config.rb, line 234
def enabled_spies
  # check if the framework is rails or sinatra
  sinatra_activerecord_spies = %w[
    sinatra
    sinatra_activerecord/mysql_adapter
    sinatra_activerecord/postgresql_adapter
    sinatra_activerecord/sqlite_adapter
  ]

  new_available_spies = if defined? ::Sinatra::Base
                          if defined? ActiveRecord
                            available_spies + sinatra_activerecord_spies
                          else
                            available_spies
                          end
                        else
                          available_spies
                        end

  new_available_spies + prefix_spies - disabled_spies
end
prefix_spies() click to toggle source
# File lib/stackify_apm/config.rb, line 224
def prefix_spies
  return [] unless @prefix_enabled
  %w[
    logger
    logging
    log4r
    yell
  ]
end

Private Instance Methods

assign(options) click to toggle source
# File lib/stackify_apm/config.rb, line 272
def assign(options)
  options.each do |key, value|
    begin
      send("#{key}=", value)
    rescue Exception => e
      info "[Config] Key: '#{key}' doesn't exist."
    end
  end
end
build_logger() click to toggle source

rubocop:enable Naming/AccessorMethodName

# File lib/stackify_apm/config.rb, line 337
def build_logger
  debugger_logpath = log_path == '-' ? $stdout : log_path
  logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
  logger.level = log_level
  self.logger = logger
end
format_name(str) click to toggle source
# File lib/stackify_apm/config.rb, line 344
def format_name(str)
  str.gsub('::', '_')
end
load_stackify_props_linux() click to toggle source

rubocop:disable Metrics/CyclomaticComplexity

# File lib/stackify_apm/config.rb, line 349
def load_stackify_props_linux
  @client_id = nil
  @device_id = nil
  @client_run_domain = nil
  begin
    info '[Config] Reading the stackify.properties file'
    IO.foreach(@stackify_properties_file) do |line|
      case line.downcase
      when /clientid=\d+/
        cid = line.split('=')[1].strip
        @client_id = "C#{cid}"
      when /deviceid=\d+/
        devid = line.split('=')[1].strip
        @device_id = "CD#{devid}"
      when /clientrumdomain=([\w\s\d\"\']+)+/i
        @client_run_domain = line.split('=')[1].strip
      end
    end
    info "[Config] stackify.properties: clientId=#{@client_id}, deviceId=#{@device_id}, client_rum_domain=#{@client_run_domain}"
  rescue StandardError => e
    info '[Config] Error occured while reading the stackify.properties file.'
    info e.inspect
  end
  info '[Config] No clientId found from stackify.properties file.' if @client_id.nil?
  info '[Config] No deviceId found from stackify.properties file.' if @device_id.nil?
  info '[Config] No client RUM domain found from stackify.properties file.' if @client_run_domain.nil?
end
load_stackify_props_windows() click to toggle source

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity

# File lib/stackify_apm/config.rb, line 380
def load_stackify_props_windows
  require 'win32ole'
  @client_id = nil
  @device_id = nil
  @client_run_domain = nil
  begin
    info '[Config] Reading the Stackify props in Environment variables'
    @client_run_domain = ENV['STACKIFY_RUM_DOMAIN'] || nil
    if ENV['STACKIFY_ENV']
      props = ENV['STACKIFY_ENV'].split('|')
      @client_id = props[0].to_s if props[0]
      @device_id = props[1].to_s if props[1]
      info "[Config] stackify.properties: clientId=#{@client_id}, deviceId=#{@device_id}, client_rum_domain=#{@client_run_domain}"
    end
  rescue StandardError => e
    info '[Config] Error occured while reading the Stackify props in Environment variables.'
    info e.inspect
  end
  info '[Config] No clientId found in environment variables.' if @client_id.nil?
  info '[Config] No deviceId found in environment variables.' if @device_id.nil?
  info '[Config] No client RUM domain found in environment variables.' if @client_run_domain.nil?
end
set_defaults() click to toggle source
# File lib/stackify_apm/config.rb, line 282
def set_defaults
  assign(DEFAULTS)
end
set_from_args(options) click to toggle source

rubocop:disable Naming/AccessorMethodName

# File lib/stackify_apm/config.rb, line 308
def set_from_args(options)
  assign(options)
end
set_from_config_file() click to toggle source

rubocop:enable Naming/AccessorMethodName

# File lib/stackify_apm/config.rb, line 313
def set_from_config_file
  return unless File.exist?(config_file)

  assign(YAML.load_file(config_file) || {})
end
set_from_env() click to toggle source

rubocop:disable Metrics/CyclomaticComplexity

# File lib/stackify_apm/config.rb, line 287
def set_from_env
  ENV_TO_KEY.each do |env_key, key|
    next unless (value = ENV[env_key])

    type, key = key if key.is_a? Array

    value =
      case type
      when :int then value.to_i
      when :float then value.to_f
      when :bool then !%w[0 false].include?(value.strip.downcase)
      when :list then value.split(/[ ,]/)
      else value
      end

    send("#{key}=", value)
  end
end
set_prefix_paths() click to toggle source

set log paths to prefix path if prefix_enabled is true

# File lib/stackify_apm/config.rb, line 320
def set_prefix_paths
  all_user_profile = ENV['ALLUSERSPROFILE'] || "C:\\ProgramData"

  @log_path = StackifyRubyAPM::Util.host_os == 'WINDOWS' ? "#{all_user_profile}\\Stackify\\Agent\\debug\\stackify-ruby-apm-1.log" : "/usr/local/prefix/debug/stackify-ruby-apm-1.log"
  @log_trace_path = StackifyRubyAPM::Util.host_os == 'WINDOWS' ? "#{all_user_profile}\\Stackify\\Agent\\log\\" : '/usr/local/prefix/log/'
end
set_rails(app) click to toggle source

rubocop:disable Naming/AccessorMethodName

# File lib/stackify_apm/config.rb, line 328
def set_rails(app)
  self.application_name ||= format_name(application_name || app.class.parent_name).strip
  self.logger ||= Rails.logger

  self.root_path = Rails.root.to_s
  self.view_paths = app.config.paths['app/views'].existent
end
validate_apm_yml() click to toggle source

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity

# File lib/stackify_apm/config.rb, line 407
def validate_apm_yml
  info '[Config] rum_enabled must be Boolean type: true/false.' unless [TrueClass, FalseClass].include?(@rum_enabled.class) && defined?(@rum_enabled)
  info '[Config] rum_auto_injection must be Boolean type: true/false.' unless [TrueClass, FalseClass].include?(@rum_auto_injection.class) && defined?(@rum_auto_injection)
  info '[Config] application_name must be String type.' unless @application_name.is_a?(String) && defined?(@application_name)
  info '[Config] environment_name must be String type.' unless @environment_name.is_a?(String) && defined?(@environment_name)
  info '[Config] transport must be String type.' unless @transport.is_a?(String) && defined?(@transport)
  info '[Config] Transport should be one of these values: [agent_socket, default, agent_http]. Should be a String.' if defined?(@transport) && !%w[agent_socket default agent_http].include?(@transport.downcase)
  info '[Config] prefix_enabled must be Boolean type: true/false.' unless [TrueClass, FalseClass].include?(@prefix_enabled.class) && defined?(@prefix_enabled)
end