Class: Nines::App
- Inherits:
-
Object
- Object
- Nines::App
- Defined in:
- lib/nines/app.rb
Class Attribute Summary collapse
-
.config ⇒ Object
Returns the value of attribute config.
-
.continue ⇒ Object
Returns the value of attribute continue.
-
.debug ⇒ Object
Returns the value of attribute debug.
-
.email_from ⇒ Object
Returns the value of attribute email_from.
-
.email_subject_prefix ⇒ Object
Returns the value of attribute email_subject_prefix.
-
.logfile ⇒ Object
Returns the value of attribute logfile.
-
.logger ⇒ Object
Returns the value of attribute logger.
-
.notifier ⇒ Object
Returns the value of attribute notifier.
-
.pidfile ⇒ Object
Returns the value of attribute pidfile.
-
.root ⇒ Object
Returns the value of attribute root.
-
.verbose ⇒ Object
Returns the value of attribute verbose.
Instance Method Summary collapse
-
#check_hostnames ⇒ Object
make sure you’re not using OpenDNS or something else that resolves invalid names.
-
#config ⇒ Object
shortcuts.
- #configure_smtp ⇒ Object
- #debug ⇒ Object
-
#initialize(config_file) ⇒ App
constructor
A new instance of App.
- #logfile ⇒ Object
- #logfile_writable ⇒ Object
- #logger ⇒ Object
- #pidfile ⇒ Object
- #pidfile_writable ⇒ Object
- #running? ⇒ Boolean
- #start(options = {}) ⇒ Object
- #stop(options = {}) ⇒ Object
- #stringify_keys_and_symbols(obj) ⇒ Object
Constructor Details
#initialize(config_file) ⇒ App
Returns a new instance of App.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/nines/app.rb', line 14 def initialize(config_file) self.class.root = File.('../../../', __FILE__) # load config files case File.extname(config_file) when '.yml' then self.class.config = YAML.load(ERB.new(File.read(config_file)).result) when '.rb' then require config_file end self.class.config = stringify_keys_and_symbols(self.class.config) # set main parameters self.class.debug = config['debug'] self.class.verbose = config['verbose'] self.class.logfile = config['logfile'] || 'nines.log' self.class.pidfile = config['pidfile'] || 'nines.pid' self.class.email_from = config['email_from'] || 'Nines Notifier <[email protected]>' self.class.email_subject_prefix = config['email_subject_prefix'] || '' end |
Class Attribute Details
.config ⇒ Object
Returns the value of attribute config.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def config @config end |
.continue ⇒ Object
Returns the value of attribute continue.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def continue @continue end |
.debug ⇒ Object
Returns the value of attribute debug.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def debug @debug end |
.email_from ⇒ Object
Returns the value of attribute email_from.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def email_from @email_from end |
.email_subject_prefix ⇒ Object
Returns the value of attribute email_subject_prefix.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def email_subject_prefix @email_subject_prefix end |
.logfile ⇒ Object
Returns the value of attribute logfile.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def logfile @logfile end |
.logger ⇒ Object
Returns the value of attribute logger.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def logger @logger end |
.notifier ⇒ Object
Returns the value of attribute notifier.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def notifier @notifier end |
.pidfile ⇒ Object
Returns the value of attribute pidfile.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def pidfile @pidfile end |
.root ⇒ Object
Returns the value of attribute root.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def root @root end |
.verbose ⇒ Object
Returns the value of attribute verbose.
9 10 11 |
# File 'lib/nines/app.rb', line 9 def verbose @verbose end |
Instance Method Details
#check_hostnames ⇒ Object
make sure you’re not using OpenDNS or something else that resolves invalid names
88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/nines/app.rb', line 88 def check_hostnames all_good = true @check_groups.each do |group| group.checks.each do |check| unless check.hostname && Dnsruby::Resolv.getaddress(check.hostname) puts "Error: check #{check.name} has invalid hostname '#{check.hostname}'" all_good = false end end end all_good end |
#config ⇒ Object
shortcuts
35 |
# File 'lib/nines/app.rb', line 35 def config ; self.class.config ; end |
#configure_smtp ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/nines/app.rb', line 103 def configure_smtp if config['smtp'].is_a?(Hash) Mail.defaults do delivery_method :smtp, { :address => Nines::App.config['smtp']['address'] || 'localhost', :port => Nines::App.config['smtp']['port'] || 25, :domain => Nines::App.config['smtp']['domain'], :user_name => Nines::App.config['smtp']['user_name'], :password => Nines::App.config['smtp']['password'], :authentication => (Nines::App.config['smtp']['authentication'] || 'plain').to_sym, :enable_starttls_auto => Nines::App.config['smtp']['enable_starttls_auto'], :tls => Nines::App.config['smtp']['tls'], } end end end |
#debug ⇒ Object
38 |
# File 'lib/nines/app.rb', line 38 def debug ; self.class.debug ; end |
#logfile ⇒ Object
36 |
# File 'lib/nines/app.rb', line 36 def logfile ; self.class.logfile ; end |
#logfile_writable ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/nines/app.rb', line 67 def logfile_writable begin File.open(logfile, 'a') { } true rescue Exception => e puts "Exception: #{e}" false end end |
#logger ⇒ Object
39 |
# File 'lib/nines/app.rb', line 39 def logger ; self.class.logger ; end |
#pidfile ⇒ Object
37 |
# File 'lib/nines/app.rb', line 37 def pidfile ; self.class.pidfile ; end |
#pidfile_writable ⇒ Object
77 78 79 80 81 82 83 84 85 |
# File 'lib/nines/app.rb', line 77 def pidfile_writable begin File.open(pidfile, 'a') { } true rescue Exception => e puts "Exception: #{e}" false end end |
#running? ⇒ Boolean
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/nines/app.rb', line 41 def running? pid = nil begin pid = File.open(pidfile).read.to_i return false if pid == 0 rescue # puts "Pidfile doesn't exist" return false end begin Process.kill(0, pid) # puts "#{pid} is running" return true rescue Errno::EPERM # puts "No permission to query #{pid}!" rescue Errno::ESRCH # puts "#{pid} is NOT running." rescue # puts "Unable to determine status for #{pid} : #{$!}" end false end |
#start(options = {}) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 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 202 |
# File 'lib/nines/app.rb', line 134 def start( = {}) # set up logger self.class.logger = Logger.new(debug ? STDOUT : File.open(logfile, 'a')) logger.sync = 1 # makes it possible to tail the logfile # use it logger.puts "[#{Time.now}] - nines starting" # set up notifier configure_smtp self.class.notifier = Notifier.new(config['contacts']) # set up check_groups (uses logger and notifier) if !config['check_groups'].is_a?(Array) || config['check_groups'].empty? raise Exception.new("No check groups configured, nothing to do.") end @check_groups = [] config['check_groups'].each do || @check_groups << CheckGroup.new() end # TODO: this is a little awkwardly placed, but can fix later unless check_hostnames puts "Invalid hostnames found in config file" exit 1 end # fork and detach if pid = fork File.open(pidfile, 'w') { |f| f.print pid } puts "Background process started with pid #{pid} (end it using `#{$0} stop`)" puts "Debug mode enabled, background process will log to STDOUT and exit after running each check once." if debug exit 0 end # # rest of this method runs as background process # # trap signals before spawning threads self.class.continue = true trap("INT") { Nines::App.continue = false ; puts "Caught SIGINT, will exit after current checks complete or time out." } trap("TERM") { Nines::App.continue = false ; puts "Caught SIGTERM, will exit after current checks complete or time out." } # iterate through config, spawning check threads as we go @threads = [] @check_groups.each do |group| group.checks.each do |check| @threads << Thread.new(Thread.current) { |parent| begin check.run rescue Exception => e parent.raise e end } end end @threads.each { |t| t.join if t.alive? } logger.puts "[#{Time.now}] - nines finished" logger.close File.unlink(pidfile) puts "Background process finished" end |
#stop(options = {}) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/nines/app.rb', line 204 def stop( = {}) begin pid = File.read(pidfile).to_i if pid == 0 STDERR.puts "nines does not appear to be running." exit 1 end rescue Errno::ENOENT => e STDERR.puts "Couldn't open pid file #{pidfile}, please check your config." exit 1 end begin Process.kill "INT", pid exit 0 rescue Errno::EPERM => e STDERR.puts "Couldn't kill process with pid #{pid}, appears to be owned by someone else." exit 1 rescue Errno::ESRCH => e STDERR.puts "Couldn't kill process with pid #{pid}. Are you sure it's running?" exit 1 end end |
#stringify_keys_and_symbols(obj) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/nines/app.rb', line 120 def stringify_keys_and_symbols(obj) case obj.class.to_s when 'Array' obj.map! { |el| stringify_keys_and_symbols(el) } when 'Hash' obj.stringify_keys! obj.each { |k,v| obj[k] = stringify_keys_and_symbols(v) } when 'Symbol' obj = obj.to_s end obj end |