Class: RorVsWild::Agent

Inherits:
Object
  • Object
show all
Defined in:
lib/rorvswild/agent.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Agent

Returns a new instance of Agent.



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rorvswild/agent.rb', line 27

def initialize(config)
  @config = self.class.default_config.merge(config)
  load_features
  @client = Client.new(@config)
  @queue = config[:queue] || Queue.new(client)
  @locator = RorVsWild::Locator.new
  Host.load_config(config)
  Deployment.load_config(config)

  RorVsWild.logger.debug("Start RorVsWild #{RorVsWild::VERSION}")
  setup_plugins
  cleanup_data
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



25
26
27
# File 'lib/rorvswild/agent.rb', line 25

def client
  @client
end

#configObject (readonly)

Returns the value of attribute config.



25
26
27
# File 'lib/rorvswild/agent.rb', line 25

def config
  @config
end

#locatorObject (readonly)

Returns the value of attribute locator.



25
26
27
# File 'lib/rorvswild/agent.rb', line 25

def locator
  @locator
end

#queueObject (readonly)

Returns the value of attribute queue.



25
26
27
# File 'lib/rorvswild/agent.rb', line 25

def queue
  @queue
end

Class Method Details

.default_configObject



7
8
9
10
11
12
13
14
15
# File 'lib/rorvswild/agent.rb', line 7

def self.default_config
  {
    api_url: "https://www.rorvswild.com/api/v1",
    ignore_exceptions: default_ignored_exceptions,
    ignore_requests: [],
    ignore_plugins: [],
    ignore_jobs: [],
  }
end

.default_ignored_exceptionsObject



17
18
19
20
21
22
23
# File 'lib/rorvswild/agent.rb', line 17

def self.default_ignored_exceptions
  if defined?(ActionDispatch::ExceptionWrapper)
    ActionDispatch::ExceptionWrapper.rescue_responses.keys
  else
    []
  end
end

Instance Method Details

#catch_error(context = nil, &block) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/rorvswild/agent.rb', line 127

def catch_error(context = nil, &block)
  begin
    block.call
  rescue Exception => ex
    record_error(ex, context)
    ex
  end
end

#current_dataObject



146
147
148
# File 'lib/rorvswild/agent.rb', line 146

def current_data
  Thread.current[:rorvswild_data]
end

#current_executionObject



150
151
152
# File 'lib/rorvswild/agent.rb', line 150

def current_execution
  Thread.current[:rorvswild_execution]
end

#ignored_exception?(exception) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
165
166
# File 'lib/rorvswild/agent.rb', line 162

def ignored_exception?(exception)
  return false unless config[:ignore_exceptions]
  class_name = exception.class.to_s
  config[:ignore_exceptions].any? { |str_or_regex| str_or_regex === class_name }
end

#ignored_job?(name) ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/rorvswild/agent.rb', line 158

def ignored_job?(name)
  config[:ignore_jobs].any? { |str_or_regex| str_or_regex === name }
end

#ignored_request?(name) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/rorvswild/agent.rb', line 154

def ignored_request?(name)
  config[:ignore_requests].any? { |str_or_regex| str_or_regex === name }
end

#load_featuresObject



41
42
43
44
# File 'lib/rorvswild/agent.rb', line 41

def load_features
  features = config[:features] || []
  RorVsWild.logger.info("Server metrics are now monitored enabled by default") if features.include?("server_metrics")
end

#measure_block(name = nil, kind = "code".freeze, &block) ⇒ Object



60
61
62
# File 'lib/rorvswild/agent.rb', line 60

def measure_block(name = nil, kind = "code".freeze, &block)
  current_execution ? measure_section(name, kind: kind, &block) : measure_job(name, &block)
end

#measure_code(code) ⇒ Object



56
57
58
# File 'lib/rorvswild/agent.rb', line 56

def measure_code(code)
  measure_block(code) { eval(code) }
end

#measure_job(name, parameters: nil, &block) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rorvswild/agent.rb', line 100

def measure_job(name, parameters: nil, &block)
  return measure_section(name, &block) if current_execution # For recursive jobs
  return block.call if ignored_job?(name)
  start_execution(Execution::Job.new(name, parameters))
  begin
    block.call
  rescue Exception => ex
    current_execution.add_exception(ex)
    raise
  ensure
    stop_execution
  end
end

#measure_method(method) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/rorvswild/agent.rb', line 64

def measure_method(method)
  return if method.name.end_with?("_measured_by_rorvswild")
  if method.is_a?(Method)
    method_full_name = [method.receiver, method.name].join(".") # Method => class method
  else
    method_full_name = [method.owner, method.name].join("#") # UnboundMethod => instance method
  end
  method_alias = :"#{method.name}_measured_by_rorvswild"
  return if method.owner.method_defined?(method_alias)
  method.owner.alias_method(method_alias, method.name)
  method_file, method_line = method.source_location
  method_file = locator.relative_path(File.expand_path(method_file))
  method.owner.define_method(method.name) do |*args|
    section = Section.start
    section.file = method_file
    section.line = method_line
    section.commands << method_full_name
    result = send(method_alias, *args)
    Section.stop
    result
  end
end

#measure_section(name, kind: "code", &block) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rorvswild/agent.rb', line 87

def measure_section(name, kind: "code", &block)
  return block.call unless current_execution
  begin
    RorVsWild::Section.start do |section|
      section.commands << name
      section.kind = kind
    end
    block.call
  ensure
    RorVsWild::Section.stop
  end
end

#merge_error_context(hash) ⇒ Object



142
143
144
# File 'lib/rorvswild/agent.rb', line 142

def merge_error_context(hash)
  current_execution && current_execution.merge_error_context(hash)
end

#record_error(exception, context = nil) ⇒ Object



136
137
138
139
140
# File 'lib/rorvswild/agent.rb', line 136

def record_error(exception, context = nil)
  if !ignored_exception?(exception) && current_execution&.error&.exception != exception
    queue_error(Error.new(exception, context).as_json)
  end
end

#setup_pluginsObject



46
47
48
49
50
51
52
53
54
# File 'lib/rorvswild/agent.rb', line 46

def setup_plugins
  for name in RorVsWild::Plugin.constants
    next if config[:ignore_plugins] && config[:ignore_plugins].include?(name.to_s)
    if (plugin = RorVsWild::Plugin.const_get(name)).respond_to?(:setup)
      RorVsWild.logger.debug("Setup RorVsWild::Plugin::#{name}")
      plugin.setup(self)
    end
  end
end

#start_execution(execution) ⇒ Object



114
115
116
# File 'lib/rorvswild/agent.rb', line 114

def start_execution(execution)
  Thread.current[:rorvswild_execution] ||= execution
end

#stop_executionObject



118
119
120
121
122
123
124
125
# File 'lib/rorvswild/agent.rb', line 118

def stop_execution
  return unless execution = current_execution
  execution.stop
  case execution
  when Execution::Job then queue_job
  when Execution::Request then queue_request
  end
end