require 'eventmachine' require 'ganymed' require 'ganymed/client' module Ganymed ## # The Collector polls various system-level metrics that are not pushed to the # {Processor} automatically. # class Collector # The configuration object. attr_reader :config # The {Client} object. attr_reader :client # Create a new collector instance and initialize all configured collectors. # # @param [Configuration] config The configuration object. def initialize(config) @config = config @client = Client.new(:processor => @config.client.processor, :sampler => @config.client.sampler) load_collectors @config.collectors.each do |collector| log.info("initializing collector #{collector.klass.demodulize}") collector.klass.constantize.new(collector, self).run end end def load_collectors # collectors shipped with ganymed Dir[File.join(Ganymed::LIB_DIR, 'ganymed/collector/*.rb')].each do |f| log.debug("Loading collector from #{f}") require f end # custom collectors if @config.collector.path.tap{} Dir[File.join(@config.collector.path, '*.rb')].each do |f| log.debug("Loading collector from #{f}") require f end end end ## # A base class for collectors. # class Base # Create a new data collector instance. # # @param [Configuration] config The configuration object. # @param [Collector] collector The collector instance. def initialize(config, collector) @config, @collector = config, collector @processor = @collector.client.processor @sampler = @collector.client.sampler end # Start the EventMachine timer to collect metrics at the specified # interval. def run timer do begin collect! rescue Exception => e log.exception(e) end end end # @private def timer if interval EM.add_periodic_timer(interval) do EM.defer { yield } end else yield end end # The interval used to collect metrics. Either taken from the # configuration file or overriden by subclasses. def interval @config.interval.tap{} or @collector.config.resolution end # This method must be implemented by subclasses to collect the desired # metrics. This function is called every #interval seconds after the # timer has been initialized by the #run method. def collect! raise NotImplementedError end end end end