lib/outpost/scout.rb in outpost-0.2.0 vs lib/outpost/scout.rb in outpost-0.2.1
- old
+ new
@@ -16,10 +16,15 @@
# Example:
# expect(:response_code) do |scout, code|
# scout.response_code == code
# end
#
+ # Scouts may also report specific data. This is useful to complement
+ # status reporting with the data received from the measurement. After the
+ # scout is run, each report data method will be executed and its calue will be
+ # added to the resulting report.
+ #
# @example an example of a Scout that parses the HTTP response code
# module Outpost
# module Scouts
# class Http < Outpost::Scout
# expect(:response_code) { |scout,code| scout.response_code == code }
@@ -38,22 +43,52 @@
# end
# end
# end
# end
#
+ # @example an example of a Scout that reports the duration of a HTTP request
+ # module Outpost
+ # module Scouts
+ # class TimedHttp < Outpost::Scout
+ # expect(:response_code) { |scout,code| scout.response_code == code }
+ #
+ # attr_reader :response_code, :response_time
+ # report_data :response_time
+ #
+ # def setup(options)
+ # @host = options[:host]
+ # @port = options[:port] || 80
+ # @path = options[:path] || '/'
+ # end
+ #
+ # def execute
+ # previous_time = Time.now
+ #
+ # response = Net::HTTP.get_response(@host, @path, @port)
+ # @response_code = response.code.to_i
+ #
+ # @response_time = Time.now - response_time
+ # end
+ # end
+ # end
+ # end
+ #
# @abstract Subclasses must override {#setup} and {#execute} to be a valid
# Scout
class Scout
+ attr_reader :report_data
+
class << self
+ attr_reader :reporting_data_methods
# Returns the hash of expectations, where the key is the name of the
# expectation and the value is the callable Object (object that responds
# to #call)
#
# @return [Hash<Symbol, Object>]
def expectations
- @expectations ? @expectations.dup : []
+ @expectations ? @expectations.dup : {}
end
# Registers a new expectation into the Scout. If the callable does not
# respond to #call, an ArgumentError will be raised.
#
@@ -72,51 +107,75 @@
@expectations[expectation] = callable
else
raise ArgumentError, 'Object must respond to method #call to be a valid expectation.'
end
end
+
+ def reporting_data_methods
+ @reporting_data_methods ||= []
+ @reporting_data_methods
+ end
+
+ def report_data(*methods)
+ @reporting_data_methods ||= []
+ @reporting_data_methods += methods
+ end
end
# @param [String, #read] description A string containing a description of
# the Scout so it may be identified in the construction of status reports.
# @param [Hash, #read] config A hash containing any number of
# configurations that will be passed to the #setup method
def initialize(description, config)
@description = description
@config = config
+ @report_data = {}
setup(config.options)
end
# Executes the Scout and go through all the registered expectations to find
# out all expectations that match and return the associated status.
#
- # @return [Symbol] the current status of the Scout (:up, :down)
+ # @return [Symbol] the current status of the Scout (:up, :down, :warning)
# @raise [NotImplementedError] raised when a configured expectation was not
# registered in the Scout.
def run
statuses = []
execute
# Response_pair contains the expectation as key and the expected value as
# value.
# Example: {:response_time => 200}
#
- # status is the status (:up or :down, for example) that will be returned
+ # status is the status (:up, :down or :warning, for example) that will be returned
# in case the expectation match current system status.
- @config.reports.each do |response_pair, status|
- response_pair.each do |expectation, value|
- if self.class.expectations[expectation].nil?
- message = "expectation '#{expectation}' wasn't implemented by #{self.class.name}"
- raise NotImplementedError, message
- end
+ if @config.reports.present?
+ @config.reports.each do |response_pair, status|
+ response_pair.each do |expectation, value|
+ if self.class.expectations[expectation].nil?
+ message = "expectation '#{expectation}' wasn't implemented by #{self.class.name}"
+ raise NotImplementedError, message
+ end
- if self.class.expectations[expectation].call(self, value)
- statuses << status
+ if self.class.expectations[expectation].call(self, value)
+ statuses << status
+ end
end
end
end
+ gather_reporting_data
Report.summarize(statuses)
+ end
+
+ def gather_reporting_data
+ self.class.reporting_data_methods.each do |method|
+ if respond_to?(method)
+ @report_data[method.to_sym] = send(method)
+ else
+ raise ArgumentError, "Scout #{self.class.name} does not respond to ##{method} reporting data method"
+ end
+ end
end
# Called when the scout object is being constructed. Arguments can be
# everything the developer set in the creation of Outpost.
#