Class: ScoutAgent::Mission

Inherits:
Object
  • Object
show all
Defined in:
lib/scout_agent/mission.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, name, last_run, memory, options) ⇒ Mission

Creates a new Scout Plugin to run.



35
36
37
38
39
40
41
42
43
# File 'lib/scout_agent/mission.rb', line 35

def initialize(id, name, last_run, memory, options)
  @id             = id
  @name           = name
  @last_run       = last_run
  @memory         = memory
  @options        = options
  @mission_log_db = Database.load(:mission_log)
  @queue_db       = Database.load(:queue)
end

Class Attribute Details

.preparedObject (readonly)

Returns the value of attribute prepared.



7
8
9
# File 'lib/scout_agent/mission.rb', line 7

def prepared
  @prepared
end

Instance Attribute Details

#last_runObject (readonly)

Returns the value of attribute last_run.



45
46
47
# File 'lib/scout_agent/mission.rb', line 45

def last_run
  @last_run
end

Class Method Details

.inherited(new_plugin) ⇒ Object



10
11
12
# File 'lib/scout_agent/mission.rb', line 10

def self.inherited(new_plugin)
  @prepared = new_plugin
end

.needs(*libraries) ⇒ Object

You can use this method to indicate one or more libraries your plugin requires:

class MyNeedyPlugin < Scout::Plugin
  needs "faster_csv", "elif"
  # ...
end

Your build_report() method will not be called if all libraries cannot be loaded. RubyGems will be loaded if needed to find the libraries.



26
27
28
29
30
31
32
# File 'lib/scout_agent/mission.rb', line 26

def self.needs(*libraries)
  if libraries.empty?
    @needs ||= [ ]
  else
    needs.push(*libraries.flatten)
  end
end

Instance Method Details

#data_for_serverObject

Builds the data to send to the server.

We programatically define several helper methods for creating this data.

Usage:

reports << {:data => "here"}
report(:data => "here")
add_report(:data => "here")

alerts << {:subject => "subject", :body => "body"}
alert("subject", "body")
alert(:subject => "subject", :body => "body")
add_alert("subject", "body")
add_alert(:subject => "subject", :body => "body")

errors << {:subject => "subject", :body => "body"}
error("subject", "body")
error(:subject => "subject", :body => "body")
add_error("subject", "body")
add_error(:subject => "subject", :body => "body")


74
75
76
77
78
79
80
# File 'lib/scout_agent/mission.rb', line 74

def data_for_server
  @data_for_server ||= { :reports => [ ],
                         :hints   => [ ],
                         :alerts  => [ ],
                         :errors  => [ ],
                         :memory  => { } }
end

#each_queued_message(&block) ⇒ Object



134
135
136
137
138
139
140
141
142
143
# File 'lib/scout_agent/mission.rb', line 134

def each_queued_message(&block)
  while message = @queue_db.peek(@id)
    if block.arity == 1
      block[message[:fields]]
    else
      block[message[:fields], message[:created_at]]
    end
    @queue_db.dequeue(message[:id]) or return # prevent infinite loop
  end
end

#memory(name = nil) ⇒ Object

Usage:

memory(:no_track)
memory.delete(:no_track)
memory.clear


110
111
112
113
114
115
116
117
# File 'lib/scout_agent/mission.rb', line 110

def memory(name = nil)
  if name.nil?
    data_for_server[:memory]
  else
    @memory[name] ||
    @memory[name.is_a?(String) ? name.to_sym : String(name)]
  end
end

#option(name) ⇒ Object



47
48
49
50
# File 'lib/scout_agent/mission.rb', line 47

def option(name)
  @options[name] ||
  @options[name.is_a?(String) ? name.to_sym : String(name)]
end

#remember(*args) ⇒ Object

Usage:

remember(:name, value)
remember(:name1, value1, :name2, value2)
remember(:name => value)
remember(:name1 => value1, :name2 => value2)
remember(:name1, value1, :name2 => value2)


128
129
130
131
132
# File 'lib/scout_agent/mission.rb', line 128

def remember(*args)
  hashes, other = args.partition { |value| value.is_a? Hash }
  hashes.each { |hash| memory.merge!(hash) }
  (0...other.size).step(2) { |i| memory.merge!(other[i] => other[i + 1]) }
end

#runObject

Old plugins will work because they override this method. New plugins can now leave this method in place, add a build_report() method instead, and use the new helper methods to build up content inside which will automatically be returned as the end result of the run.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/scout_agent/mission.rb', line 151

def run
  # 
  # run the plugin in a new Thread so signals will be handled in the main
  # Thread and not accidentally caught by rescue clauses in the body of the
  # mission
  # 
  Thread.new do
    Thread.current.abort_on_exception = true
    if self.class.needs.all? { |l| library_available?(l) }
      begin
        build_report
      rescue Exception
        raise if $!.is_a? SystemExit  # don't catch exit() calls
        error "#{@name} run failed with an error", <<-END_ERROR.trim
        Error:
          #{$!.class}
        Message:
          #{$!.message}
        Backtrace:
        #{$!.backtrace.map { |line| "  #{line}\n" }.join}
        END_ERROR
      end
    end
  end.join  # wait for completion so we have reports to write
  write_reports_and_update_memory
end