Class: AppMap::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/appmap/config.rb

Defined Under Namespace

Classes: Hook, Package

Constant Summary collapse

OPENSSL_PACKAGE =
Package.new('openssl', package_name: 'openssl', labels: %w[security crypto])
HOOKED_METHODS =

Methods that should always be hooked, with their containing package and labels that should be applied to them.

{
  'ActiveSupport::SecurityUtils' => Hook.new(:secure_compare, Package.new('active_support', package_name: 'active_support', labels: %w[security crypto]))
}.freeze
BUILTIN_METHODS =
{
  'OpenSSL::PKey::PKey' => Hook.new(:sign, OPENSSL_PACKAGE),
  'Digest::Instance' => Hook.new(:digest, OPENSSL_PACKAGE),
  'OpenSSL::X509::Request' => Hook.new(i[sign verify], OPENSSL_PACKAGE),
  'OpenSSL::PKCS5' => Hook.new(i[pbkdf2_hmac_sha1 pbkdf2_hmac], OPENSSL_PACKAGE),
  'OpenSSL::Cipher' => Hook.new(i[encrypt decrypt final], OPENSSL_PACKAGE),
  'OpenSSL::X509::Certificate' => Hook.new(:sign, OPENSSL_PACKAGE),
  'Logger' => Hook.new(:add, Package.new('logger', labels: %w[log io])),
  'Net::HTTP' => Hook.new(:request, Package.new('net/http', package_name: 'net/http', labels: %w[http io])),
  'Net::SMTP' => Hook.new(:send, Package.new('net/smtp', package_name: 'net/smtp', labels: %w[smtp email io])),
  'Net::POP3' => Hook.new(:mails, Package.new('net/pop3', package_name: 'net/pop', labels: %w[pop pop3 email io])),
  'Net::IMAP' => Hook.new(:send_command, Package.new('net/imap', package_name: 'net/imap', labels: %w[imap email io])),
  'IO' => Hook.new(i[read write open close], Package.new('io', labels: %w[io])),
  'Marshal' => Hook.new(i[dump load], Package.new('marshal', labels: %w[serialization marshal])),
  'Psych' => Hook.new(i[dump dump_stream load load_stream parse parse_stream], Package.new('yaml', package_name: 'psych', labels: %w[serialization yaml])),
  'JSON::Ext::Parser' => Hook.new(:parse, Package.new('json', package_name: 'json', labels: %w[serialization json])),
  'JSON::Ext::Generator::State' => Hook.new(:generate, Package.new('json', package_name: 'json', labels: %w[serialization json]))
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, packages = []) ⇒ Config

Returns a new instance of Config.



52
53
54
55
# File 'lib/appmap/config.rb', line 52

def initialize(name, packages = [])
  @name = name
  @packages = packages
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



50
51
52
# File 'lib/appmap/config.rb', line 50

def name
  @name
end

#packagesObject (readonly)

Returns the value of attribute packages.



50
51
52
# File 'lib/appmap/config.rb', line 50

def packages
  @packages
end

Class Method Details

.load(config_data) ⇒ Object

Loads configuration from a Hash.



65
66
67
68
69
70
# File 'lib/appmap/config.rb', line 65

def load(config_data)
  packages = (config_data['packages'] || []).map do |package|
    Package.new(package['path'], exclude: package['exclude'] || [])
  end
  Config.new config_data['name'], packages
end

.load_from_file(config_file_name) ⇒ Object

Loads configuration data from a file, specified by the file name.



59
60
61
62
# File 'lib/appmap/config.rb', line 59

def load_from_file(config_file_name)
  require 'yaml'
  load YAML.safe_load(::File.read(config_file_name))
end

Instance Method Details

#always_hook?(defined_class, method_name) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/appmap/config.rb', line 100

def always_hook?(defined_class, method_name)
  !!find_package(defined_class, method_name)
end

#find_hook(defined_class) ⇒ Object



111
112
113
# File 'lib/appmap/config.rb', line 111

def find_hook(defined_class)
  HOOKED_METHODS[defined_class] || BUILTIN_METHODS[defined_class]
end

#find_package(defined_class, method_name) ⇒ Object



104
105
106
107
108
109
# File 'lib/appmap/config.rb', line 104

def find_package(defined_class, method_name)
  hook = find_hook(defined_class)
  return nil unless hook

  Array(hook.method_names).include?(method_name) ? hook.package : nil      
end

#included_by_location?(method) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/appmap/config.rb', line 96

def included_by_location?(method)
  !!package_for_method(method)
end

#package_for_method(method) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/appmap/config.rb', line 80

def package_for_method(method)
  defined_class, _, method_name = ::AppMap::Hook.qualify_method_name(method)
  package = find_package(defined_class, method_name)
  return package if package

  location = method.source_location
  location_file, = location
  return unless location_file

  location_file = location_file[Dir.pwd.length + 1..-1] if location_file.index(Dir.pwd) == 0
  packages.find do |pkg|
    (location_file.index(pkg.path) == 0) &&
      !pkg.exclude.find { |p| location_file.index(p) }
  end
end

#to_hObject



73
74
75
76
77
78
# File 'lib/appmap/config.rb', line 73

def to_h
  {
    name: name,
    packages: packages.map(&:to_h)
  }
end