class Panoptimon::Monitor
Attributes
bus[R]
cached[R]
collectors[R]
config[R]
loaded_plugins[R]
owd[R]
plugins[R]
Public Class Methods
new(args={})
click to toggle source
# File lib/panoptimon/monitor.rb, line 11 def initialize (args={}) @collectors = [] @plugins = {} @loaded_plugins = {} args.each { |k,v| instance_variable_set("@#{k}", v) } @owd = Dir.pwd me = self @bus = EM.spawn { |metric| me.bus_driver(metric) } end
Public Instance Methods
_autodetect_collector_command_path(name)
click to toggle source
Searches for ‘pancollect-’ executables in $PATH Returns nil if no command found
# File lib/panoptimon/monitor.rb, line 73 def _autodetect_collector_command_path(name) pathdirs = ENV["PATH"].split(":") name = 'pancollect-' + name pathdirs.each{|basepath| path = File.join(basepath, name) logger.debug "checking path #{path}" return path if File.exists?(path) } return nil end
_dirjson(x)
click to toggle source
Search directories for JSON files
# File lib/panoptimon/monitor.rb, line 24 def _dirjson (x) x = Pathname.new(x) x.entries.find_all {|f| f.to_s =~ /\.json$/i}. map {|f| x + f} end
_init_collector(conf)
click to toggle source
# File lib/panoptimon/monitor.rb, line 84 def _init_collector (conf) name = conf.delete(:name) command = conf.delete(:command) full_cmd = [command.to_s] + conf[:args].to_a logger.debug "#{name} command: #{full_cmd}" collector = Collector.new( name: name, bus: @bus, command: full_cmd, config: conf, ) collectors << collector end
_init_plugin(conf)
click to toggle source
# File lib/panoptimon/monitor.rb, line 129 def _init_plugin (conf) name = conf.delete(:name) rb = conf.delete(:rb) setup = eval("->(name, config, monitor) {#{rb.open.read}\n}", empty_binding, rb.to_s, 1) callback = begin; setup.call(name, conf, self) rescue; raise "error loading plugin '#{name}' - #{$!}"; end logger.debug "plugin #{callback} - #{plugins[name]}" plugins[name] = callback unless callback.nil? loaded_plugins[name] = conf.clone # XXX need a plugin object? end
_load_collector_config(file)
click to toggle source
# File lib/panoptimon/monitor.rb, line 49 def _load_collector_config (file) conf = JSON.parse(file.read, {:symbolize_names => true}) # Determine the command path collector_name = file.basename.sub(/\.json$/, '').to_s command = Pathname.new(conf[:exec] || collector_name) command = file.dirname + collector_name + command \ unless command.absolute? command = _autodetect_collector_command_path(collector_name) \ unless command.exist? || !conf[:exec].nil? # TODO - interval/timeout defaults should be configurable return conf. merge({ name: collector_name, interval: (self.config.collector_interval || 99).to_i, timeout: (self.config.collector_timeout || 99).to_i }) {|k,a,b| a}. merge({command: command}) end
_load_plugin_config(file)
click to toggle source
# File lib/panoptimon/monitor.rb, line 112 def _load_plugin_config (file) conf = JSON.parse(file.read, {:symbolize_names => true}) base = file.basename.sub(/\.json$/, '').to_s # TODO support conf[:require] -> class.setup(conf) scheme? rb = conf[:require] || "#{base}.rb" rb = file.dirname + base + rb return conf. merge({ name: base, }) {|k,a,b| a}. merge({ base: base, rb: rb }) end
bus_driver(metric)
click to toggle source
# File lib/panoptimon/monitor.rb, line 171 def bus_driver(metric) logger.debug {"metric: #{metric.inspect}"} metric.each {|k,v| @cached[k] = v} if @cached plugins.each {|n,p| begin p.call(metric) rescue => e logger.warn "plugin '#{n}' error: " + "#{e}\n #{e.backtrace[0].sub(%r{^.*/?(plugins/)}, '\1')}" plugins.delete(n) end } end
empty_binding()
click to toggle source
# File lib/panoptimon/monitor.rb, line 107 def empty_binding; binding; end
enable_cache(arg=true)
click to toggle source
# File lib/panoptimon/monitor.rb, line 167 def enable_cache(arg=true); if arg; @cached ||= {}; else; @cached = nil; end end
find_collectors()
click to toggle source
# File lib/panoptimon/monitor.rb, line 30 def find_collectors _dirjson(config.collectors_dir) end
find_plugins()
click to toggle source
# File lib/panoptimon/monitor.rb, line 34 def find_plugins _dirjson(config.plugins_dir) end
http()
click to toggle source
# File lib/panoptimon/monitor.rb, line 98 def http return @http unless @http.nil? # TODO rescue LoadError => nicer error message require 'panoptimon/http' @http = HTTP.new logger.warn "Serving http on #{@http.hostport}" @http end
load_collectors()
click to toggle source
# File lib/panoptimon/monitor.rb, line 38 def load_collectors find_collectors.each {|f| begin _init_collector(_load_collector_config(f)) rescue => ex logger.error "collector #{f} failed to load: \n" + " #{ex.message} \n #{ex.backtrace[0]}" end } end
load_plugins()
click to toggle source
# File lib/panoptimon/monitor.rb, line 108 def load_plugins find_plugins.each {|f| _init_plugin(_load_plugin_config(f)) } end
run()
click to toggle source
# File lib/panoptimon/monitor.rb, line 141 def run runall = ->() { logger.debug "beep" collectors.each {|c| logger.info "#{c.cmd} (#{c.running? ? 'on ' : 'off' }) last run time: #{c.last_run_time}" next if c.last_run_time + c.interval > Time.now or c.running? c.run } } EM.next_tick(&runall) logger.warn 'no collectors' if collectors.length == 0 minterval = collectors.map{|c| c.interval}.min minterval = 67 if minterval.nil? # XXX should never happen logger.debug "minimum: #{minterval}" EM.add_periodic_timer(minterval, &runall); @http.start if @http end
stop()
click to toggle source
# File lib/panoptimon/monitor.rb, line 163 def stop EM.stop end