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. #