Class: Scout::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/es-scout/plugin.rb

Constant Summary collapse

EMBEDDED_OPTIONS_REGEX =
/OPTIONS ?= ?<<-?([A-Z_]+)(.*)\1/m

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(last_run, memory, options) ⇒ Plugin

Creates a new Scout Plugin to run.



55
56
57
58
59
# File 'lib/es-scout/plugin.rb', line 55

def initialize(last_run, memory, options)
  @last_run = last_run
  @memory   = memory
  @options  = options
end

Class Attribute Details

.last_definedObject

Returns the value of attribute last_defined.



11
12
13
# File 'lib/es-scout/plugin.rb', line 11

def last_defined
  @last_defined
end

Class Method Details

.extract_options_yaml_from_code(code) ⇒ Object

extracts the internal YAML, if any, and returns the YAML string. returns nil if no embedded options.



48
49
50
51
# File 'lib/es-scout/plugin.rb', line 48

def extract_options_yaml_from_code(code)
  code =~ EMBEDDED_OPTIONS_REGEX
  return $2
end

.has_embedded_options?(code) ⇒ Boolean

true if the code seems to have embedded options

Returns:

  • (Boolean)


42
43
44
# File 'lib/es-scout/plugin.rb', line 42

def has_embedded_options?(code)
  code =~ EMBEDDED_OPTIONS_REGEX
end

.inherited(new_plugin) ⇒ Object



13
14
15
# File 'lib/es-scout/plugin.rb', line 13

def inherited(new_plugin)
  @last_defined = new_plugin
end

.load(last_run, memory, options) ⇒ Object



17
18
19
# File 'lib/es-scout/plugin.rb', line 17

def load(last_run, memory, options)
  new(last_run, memory, options)
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.



33
34
35
36
37
38
39
# File 'lib/es-scout/plugin.rb', line 33

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

Instance Method Details

#counter(name, value, options = {}, &block) ⇒ Object

Usage:

counter(:rkbps, stats['rsect'] / 2, :per => :second)
counter(:rpm, request_counter, :per => :minute)
counter(:swap_ins, vmstat['pswpin'], :per => :second, :round => true)


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/es-scout/plugin.rb', line 164

def counter(name, value, options = {}, &block)
  current_time = Time.now

  if data = memory("_counter_#{name}")
    last_time, last_value = data[:time], data[:value]
    elapsed_seconds       = current_time - last_time

    # We won't log it if the value has wrapped or enough time hasn't
    # elapsed
    if value >= last_value && elapsed_seconds >= 1
      if block
        result = block.call(last_value, value)
      else
        result = value - last_value
      end

      case options[:per]
      when :second, 'second'
        result = result / elapsed_seconds.to_f
      when :minute, 'minute'
        result = result / elapsed_seconds.to_f * 60.0
      else
        raise "Unknown option for ':per': #{options[:per].inspect}"
      end

      if options[:round]
        # Backward compatibility
        options[:round] = 1 if options[:round] == true

        result = (result * (10 ** options[:round])).round / (10 ** options[:round]).to_f
      end

      report(name => result)
    end
  end

  remember("_counter_#{name}" => { :time => current_time, :value => value })
end

#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")


87
88
89
90
91
92
93
# File 'lib/es-scout/plugin.rb', line 87

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

#memory(name = nil) ⇒ Object

Usage:

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


133
134
135
136
137
138
139
140
# File 'lib/es-scout/plugin.rb', line 133

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



61
62
63
# File 'lib/es-scout/plugin.rb', line 61

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)


151
152
153
154
155
# File 'lib/es-scout/plugin.rb', line 151

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.



209
210
211
212
# File 'lib/es-scout/plugin.rb', line 209

def run
  build_report if self.class.needs.all? { |l| library_available?(l) }
  data_for_server
end