qnotifier 0.7.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -3
- data/bin/qnotifier +29 -39
- data/config/qnotifier_config.yml +1 -16
- data/lib/plugin.rb +5 -4
- data/lib/qnotifier.rb +43 -38
- data/lib/web_service.rb +74 -82
- data/plugins/system.rb +4 -4
- data/qnotifier.gemspec +6 -18
- data.tar.gz.sig +0 -0
- metadata +8 -100
- metadata.gz.sig +2 -2
- data/plugins/network.rb +0 -14
- data/plugins/rails.rb +0 -47
data/Rakefile
CHANGED
@@ -2,14 +2,14 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('qnotifier', '0.
|
5
|
+
Echoe.new('qnotifier', '1.0.0') do |p|
|
6
6
|
p.description = "The server side agent for the QNotifier monitoring system"
|
7
7
|
p.url = "http://qnotifier.com/qnotifier_gem"
|
8
8
|
p.author = "Gersham Meharg"
|
9
9
|
p.email = "gersham@qnotifier.com"
|
10
10
|
p.ignore_pattern = ["var/*", "tmp/*"]
|
11
|
-
p.runtime_dependencies = ["
|
12
|
-
p.development_dependencies = ["
|
11
|
+
p.runtime_dependencies = ["json_pure >=1.2.3"]
|
12
|
+
p.development_dependencies = ["json_pure >=1.2.3"]
|
13
13
|
p.executable_pattern = ["bin/*"]
|
14
14
|
p.install_message = "Qnotifier installed, please register by running 'qnotifier -r CODE' in order to register this server."
|
15
15
|
end
|
data/bin/qnotifier
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$LOAD_PATH.unshift( File.join( File.dirname(__FILE__), '../lib' ) )
|
3
3
|
require 'fileutils'
|
4
|
+
require "qnotifier"
|
4
5
|
|
5
6
|
module Qnotifier
|
6
7
|
class Command
|
@@ -8,8 +9,7 @@ module Qnotifier
|
|
8
9
|
def self.run(argv)
|
9
10
|
|
10
11
|
unless Process.euid == 0
|
11
|
-
puts "QNotifier should be only
|
12
|
-
exit
|
12
|
+
puts "WARNING: QNotifier should be only run by root"
|
13
13
|
end
|
14
14
|
|
15
15
|
if has_api_key?
|
@@ -37,7 +37,12 @@ module Qnotifier
|
|
37
37
|
require "qnotifier"
|
38
38
|
qnotifier = Qnotifier::MainProcess.new
|
39
39
|
qnotifier.alert(argv[1], argv[2], 3)
|
40
|
-
|
40
|
+
|
41
|
+
elsif argv.first == 'reset_alert'
|
42
|
+
require "qnotifier"
|
43
|
+
qnotifier = Qnotifier::MainProcess.new
|
44
|
+
qnotifier.alert(argv[1], argv[2], 6)
|
45
|
+
|
41
46
|
elsif argv.first == 'register'
|
42
47
|
require "qnotifier"
|
43
48
|
qnotifier = Qnotifier::MainProcess.new
|
@@ -60,7 +65,7 @@ module Qnotifier
|
|
60
65
|
setup_directories
|
61
66
|
|
62
67
|
else
|
63
|
-
puts "usage: qnotifier start | stop | restart | zap | reset | register | debug"
|
68
|
+
puts "usage: qnotifier start | stop | restart | zap | reset | register | debug | alert | reset_alert"
|
64
69
|
puts "see http://qnotifier.com for more details"
|
65
70
|
end
|
66
71
|
|
@@ -100,8 +105,6 @@ module Qnotifier
|
|
100
105
|
puts "Creating #{var_dir}"
|
101
106
|
FileUtils.mkdir_p var_dir
|
102
107
|
FileUtils.mkdir_p "#{var_dir}/plugins"
|
103
|
-
default_config_file = File.dirname(__FILE__) + "/../config/qnotifier_config.yml"
|
104
|
-
`cp #{default_config_file} #{var_dir}/qnotifier_config.yml`
|
105
108
|
readme_file = File.dirname(__FILE__) + "/../config/README"
|
106
109
|
`cp #{readme_file} #{var_dir}/plugins/README`
|
107
110
|
rescue Exception => e
|
@@ -110,6 +113,18 @@ module Qnotifier
|
|
110
113
|
exit
|
111
114
|
end
|
112
115
|
end
|
116
|
+
config_file = "/var/lib/qnotifier/qnotifier_config.yml"
|
117
|
+
unless File.exists?(config_file)
|
118
|
+
begin
|
119
|
+
puts "Setting default config file to #{config_file} (make your edits here)"
|
120
|
+
default_config_file = File.dirname(__FILE__) + "/../config/qnotifier_config.yml"
|
121
|
+
`cp #{default_config_file} #{var_dir}/qnotifier_config.yml`
|
122
|
+
rescue Exception => e
|
123
|
+
puts "Can't copy default config over: #{e}"
|
124
|
+
puts "Exiting"
|
125
|
+
exit
|
126
|
+
end
|
127
|
+
end
|
113
128
|
end
|
114
129
|
|
115
130
|
def self.setup_registration
|
@@ -124,9 +139,6 @@ module Qnotifier
|
|
124
139
|
if qnotifier.register(register_code)
|
125
140
|
puts "\nOK, the server has been successfully registered."
|
126
141
|
puts "You now can control the agent as a daemon using 'qnotifier start|stop|restart'"
|
127
|
-
copy_init
|
128
|
-
puts "Doing initial update..."
|
129
|
-
qnotifier.run
|
130
142
|
puts "\nStarting Qnotifier daemon (qnotifier start)"
|
131
143
|
`qnotifier start`
|
132
144
|
else
|
@@ -138,21 +150,8 @@ module Qnotifier
|
|
138
150
|
end
|
139
151
|
end
|
140
152
|
|
141
|
-
def self.copy_init
|
142
|
-
print "\nWould you like to install a qnotifier init script in /etc/init.d? (y/n):"
|
143
|
-
response = STDIN.gets.chomp.downcase!
|
144
|
-
if response == "y" || response == "yes"
|
145
|
-
init_file = File.dirname(__FILE__) + "/../init/qnotifier"
|
146
|
-
qnotifier_location = `which qnotifier`
|
147
|
-
if qnotifier_location
|
148
|
-
`cat #{init_file} | sed 's/QNOTIFIER_DAEMON_LOCATION/#{qnotifier_location}/' > /etc/init.d/qnotifier;chmod a+x /etc/init.d/qnotifier`
|
149
|
-
puts "Qnotifier init.d installed at /etc/init.d/qnotifier - you'll need to set it to start at various run levels"
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
153
|
def self.running
|
155
|
-
pid_file = "/var/lib/qnotifier/
|
154
|
+
pid_file = "/var/lib/qnotifier/qnotifier.pid"
|
156
155
|
if File.exists?(pid_file)
|
157
156
|
begin
|
158
157
|
pid = `cat #{pid_file}`.to_i
|
@@ -168,7 +167,7 @@ module Qnotifier
|
|
168
167
|
end
|
169
168
|
|
170
169
|
def self.zap
|
171
|
-
pid_file = "/var/lib/qnotifier/
|
170
|
+
pid_file = "/var/lib/qnotifier/qnotifier.pid"
|
172
171
|
if File.exists?(pid_file)
|
173
172
|
`rm #{pid_file}`
|
174
173
|
end
|
@@ -186,7 +185,7 @@ module Qnotifier
|
|
186
185
|
`rm #{runlock_file}`
|
187
186
|
end
|
188
187
|
|
189
|
-
pid_file = "/var/lib/qnotifier/
|
188
|
+
pid_file = "/var/lib/qnotifier/qnotifier.pid"
|
190
189
|
if running
|
191
190
|
puts "Daemon is already running, check pid #{pid_file}"
|
192
191
|
exit
|
@@ -201,29 +200,20 @@ module Qnotifier
|
|
201
200
|
STDOUT.reopen "/dev/null", "a"
|
202
201
|
STDERR.reopen STDOUT
|
203
202
|
trap("TERM") {daemon.stop; exit}
|
204
|
-
`echo #{Process.pid} > /var/lib/qnotifier/
|
205
|
-
|
206
|
-
|
207
|
-
cpid = fork do
|
208
|
-
require "qnotifier"
|
209
|
-
$0 = 'qnotifier-runner'
|
210
|
-
qnotifier = Qnotifier::MainProcess.new
|
211
|
-
qnotifier.run
|
212
|
-
end
|
213
|
-
Process.detach cpid
|
214
|
-
sleep 30
|
215
|
-
end
|
203
|
+
`echo #{Process.pid} > /var/lib/qnotifier/qnotifier.pid`
|
204
|
+
qnotifier = Qnotifier::MainProcess.new
|
205
|
+
qnotifier.run
|
216
206
|
end
|
217
207
|
Process.detach pid
|
218
208
|
end
|
219
209
|
|
220
210
|
def self.stop
|
221
211
|
puts "Stopping QNotifier..."
|
222
|
-
pid_file = "/var/lib/qnotifier/
|
212
|
+
pid_file = "/var/lib/qnotifier/qnotifier.pid"
|
223
213
|
if running
|
224
214
|
pid = `cat #{pid_file}`.to_i
|
225
215
|
Process.kill "TERM", pid
|
226
|
-
`rm /var/lib/qnotifier/
|
216
|
+
`rm /var/lib/qnotifier/qnotifier.pid`
|
227
217
|
end
|
228
218
|
end
|
229
219
|
end
|
data/config/qnotifier_config.yml
CHANGED
@@ -33,7 +33,7 @@ System:
|
|
33
33
|
# Alert if the memory is above this percent usage, 0 disables
|
34
34
|
alert_memory_threshold: 90
|
35
35
|
# Alert if the load is above this percent usage, 0 disables
|
36
|
-
alert_load_threshold:
|
36
|
+
alert_load_threshold: 2.0
|
37
37
|
# Alert if the disk is above this percent usage, 0 disables
|
38
38
|
alert_disk_threshold: 90
|
39
39
|
# Partitions which to monitor for free disk space
|
@@ -66,14 +66,6 @@ Urls:
|
|
66
66
|
enabled: false
|
67
67
|
url: "http://localhost"
|
68
68
|
|
69
|
-
# The Network Interface built-in plugin
|
70
|
-
# Not currently supported
|
71
|
-
Network:
|
72
|
-
# Enabled, set to either true or false
|
73
|
-
enabled: false
|
74
|
-
interfaces:
|
75
|
-
- eth0
|
76
|
-
|
77
69
|
# The Nginx built-in plugin
|
78
70
|
# You must compile nginx with --with-http_stub_status_module and point this url to the stub_status location
|
79
71
|
Nginx:
|
@@ -86,13 +78,6 @@ Passenger:
|
|
86
78
|
# Enabled, set to either true or false
|
87
79
|
enabled: false
|
88
80
|
|
89
|
-
# The Rails built-in plugin
|
90
|
-
# Not currently supported
|
91
|
-
Rails:
|
92
|
-
# Enabled, set to either true or false
|
93
|
-
enabled: false
|
94
|
-
log_file: "/var/www/rails/log/production.log"
|
95
|
-
|
96
81
|
# The Ruby built-in plugin
|
97
82
|
Ruby:
|
98
83
|
enabled: true
|
data/lib/plugin.rb
CHANGED
@@ -12,15 +12,15 @@ module Qnotifier
|
|
12
12
|
attr_accessor :stats
|
13
13
|
attr_accessor :config
|
14
14
|
attr_accessor :alert_count
|
15
|
-
|
15
|
+
|
16
16
|
# The run method, do not override
|
17
|
-
def run
|
17
|
+
def run
|
18
18
|
@class_name = self.class.to_s.split("::").last
|
19
19
|
@alert_count = 0
|
20
20
|
@alerts = nil
|
21
21
|
@reports = nil
|
22
22
|
@stats = nil
|
23
|
-
|
23
|
+
|
24
24
|
# Read the options from the global config and mix them in to the defaults for this plugin
|
25
25
|
if @config[@class_name]
|
26
26
|
@options = @defaults.update(@config[@class_name])
|
@@ -31,7 +31,8 @@ module Qnotifier
|
|
31
31
|
# Only run this plugin if it's enabled
|
32
32
|
return unless @options["enabled"]
|
33
33
|
|
34
|
-
|
34
|
+
puts "Plugin #{@class_name} running" if $qnotifier_debug
|
35
|
+
|
35
36
|
main
|
36
37
|
end
|
37
38
|
|
data/lib/qnotifier.rb
CHANGED
@@ -9,7 +9,7 @@ require "web_service"
|
|
9
9
|
require "storage"
|
10
10
|
|
11
11
|
module Qnotifier
|
12
|
-
VERSION = "0.
|
12
|
+
VERSION = "1.0.0".freeze
|
13
13
|
|
14
14
|
def self.log
|
15
15
|
unless @logger
|
@@ -44,62 +44,63 @@ module Qnotifier
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def run
|
48
|
-
Qnotifier.log.debug "QNotifier Running"
|
49
|
-
|
50
|
-
runlock_file = "/var/lib/qnotifier/.runlock"
|
51
|
-
if File.exists?(runlock_file)
|
52
|
-
puts "Runlock exists at #{runlock_file} - process already running? Exiting."
|
53
|
-
exit
|
54
|
-
else
|
55
|
-
`echo #{Process.pid} > #{runlock_file}`
|
56
|
-
end
|
57
|
-
|
47
|
+
def run
|
58
48
|
start_logging
|
59
49
|
load_config
|
60
50
|
|
61
|
-
|
62
|
-
|
63
|
-
@stats = {}
|
64
|
-
@report_count = 0
|
65
|
-
|
51
|
+
Qnotifier.log.info "QNotifier Starting"
|
52
|
+
|
66
53
|
if Qnotifier::Storage.get("server_disabled_pings")
|
67
54
|
Qnotifier.log.fatal "Disabled by the Qnotifer API, please re-register (qnotifier --register key) this agent to enable. Exiting."
|
68
55
|
exit
|
69
56
|
end
|
70
|
-
|
57
|
+
|
71
58
|
unless @config["api_key"]
|
72
59
|
error_message = "Missing API Key, please register this agent first."
|
73
60
|
puts error_message
|
74
61
|
Qnotifier.log.fatal error_message
|
75
62
|
exit
|
76
63
|
end
|
77
|
-
|
64
|
+
|
65
|
+
# Our Plugins
|
66
|
+
@plugins = []
|
67
|
+
|
78
68
|
# Load the built in plugins
|
79
69
|
Dir[File.dirname(__FILE__) + '/../plugins/*.rb'].each do |file|
|
80
|
-
|
70
|
+
load_plugin_file(file)
|
81
71
|
end
|
82
|
-
|
72
|
+
|
83
73
|
# Load the user plugins
|
84
74
|
Dir['/var/lib/qnotifier/plugins/*.rb'].each do |file|
|
85
|
-
|
75
|
+
load_plugin_file(file)
|
86
76
|
end
|
87
|
-
|
88
|
-
#
|
77
|
+
|
78
|
+
# Load the web service
|
89
79
|
webservice = Qnotifier::WebService.new
|
90
80
|
webservice.config = @config
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
81
|
+
|
82
|
+
loop do
|
83
|
+
@alerts = {}
|
84
|
+
@reports = {}
|
85
|
+
@stats = {}
|
86
|
+
@report_count = 0
|
87
|
+
|
88
|
+
for plugin in @plugins
|
89
|
+
run_plugin(plugin)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Send the alerts, reports and stats to the API
|
93
|
+
webservice.send_alerts(@alerts)
|
94
|
+
webservice.send_reports_stats(@reports, @stats, @alert_count)
|
95
|
+
|
96
|
+
Qnotifier::Storage.save
|
97
|
+
|
98
|
+
Qnotifier.log.debug "QNotifier Check Complete"
|
99
|
+
sleep 30
|
100
|
+
end
|
100
101
|
end
|
101
|
-
|
102
|
-
def
|
102
|
+
|
103
|
+
def load_plugin_file(file)
|
103
104
|
return unless file =~ /\.rb/
|
104
105
|
require file
|
105
106
|
class_name = "Qnotifier::#{File.basename(file, ".rb").split(/[^a-z0-9]/i).map{|w| w.capitalize}.join}"
|
@@ -114,6 +115,10 @@ module Qnotifier
|
|
114
115
|
Qnotifier.log.fatal "Attempted to load a non Qnotifier::Plugin plugin subclass at #{file} - make sure this directory only includes Qnotifier::Plugin subclasses"
|
115
116
|
return
|
116
117
|
end
|
118
|
+
@plugins << plugin
|
119
|
+
end
|
120
|
+
|
121
|
+
def run_plugin(plugin)
|
117
122
|
begin
|
118
123
|
Timeout.timeout 30 do
|
119
124
|
plugin.run
|
@@ -123,7 +128,6 @@ module Qnotifier
|
|
123
128
|
rescue Errno::ENOENT => e
|
124
129
|
Qnotifier.log.error "#{class_name} Plugin Error: #{e.message}"
|
125
130
|
end
|
126
|
-
|
127
131
|
@alerts.merge!(plugin.alerts) if plugin.alerts
|
128
132
|
@reports.merge!(plugin.reports) if plugin.reports
|
129
133
|
@stats.merge!(plugin.stats) if plugin.stats
|
@@ -140,11 +144,11 @@ module Qnotifier
|
|
140
144
|
end
|
141
145
|
|
142
146
|
Qnotifier::Storage.wipe
|
143
|
-
|
147
|
+
|
144
148
|
webservice = Qnotifier::WebService.new
|
145
149
|
webservice.config = @config
|
146
150
|
api_key = webservice.register_server(code)
|
147
|
-
|
151
|
+
|
148
152
|
if api_key
|
149
153
|
save_api_key(api_key)
|
150
154
|
return api_key
|
@@ -186,6 +190,7 @@ module Qnotifier
|
|
186
190
|
begin
|
187
191
|
@config = YAML::load(File.open('/var/lib/qnotifier/qnotifier_config.yml'))
|
188
192
|
rescue Exception => e
|
193
|
+
puts "Can't open /var/lib/qnotifier/qnotifier_config.yml"
|
189
194
|
Qnotifier.log.error "Can't open /var/lib/qnotifier/qnotifier_config.yml"
|
190
195
|
exit
|
191
196
|
end
|
data/lib/web_service.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
3
|
-
require 'json'
|
2
|
+
require 'json/pure'
|
4
3
|
require 'storage'
|
5
|
-
require '
|
4
|
+
require 'net/http'
|
6
5
|
|
7
6
|
module Qnotifier
|
8
7
|
class WebService
|
@@ -11,28 +10,28 @@ module Qnotifier
|
|
11
10
|
|
12
11
|
def initialize
|
13
12
|
@@poll_interval = 300
|
14
|
-
RestClient.proxy = ENV['http_proxy']
|
15
13
|
end
|
16
14
|
|
17
15
|
def send_alerts(alerts)
|
18
16
|
|
19
17
|
return if alerts.empty?
|
20
18
|
|
19
|
+
unless @hostname
|
20
|
+
unless @config["hostname"]
|
21
|
+
@hostname = `hostname`.strip
|
22
|
+
else
|
23
|
+
@hostname = @config["hostname"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
21
27
|
if $qnotifier_debug
|
22
28
|
puts "\nAlerts:"
|
23
|
-
|
29
|
+
puts alerts
|
24
30
|
puts "\nNot sending alerts to server due to debug mode."
|
25
31
|
return
|
26
32
|
end
|
27
33
|
|
28
34
|
Qnotifier.log.info "Sending alerts #{alerts}"
|
29
|
-
|
30
|
-
# Hostname
|
31
|
-
unless @config["hostname"]
|
32
|
-
@hostname = `hostname`.strip
|
33
|
-
else
|
34
|
-
@hostname = @config["hostname"]
|
35
|
-
end
|
36
35
|
|
37
36
|
message = {"api_key" => @config["api_key"],
|
38
37
|
"api_version" => "1.0",
|
@@ -41,28 +40,27 @@ module Qnotifier
|
|
41
40
|
"alerts" => alerts}.to_json
|
42
41
|
|
43
42
|
begin
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
43
|
+
url = URI.parse("#{@config["api_endpoint"]}/send_alert")
|
44
|
+
req = Net::HTTP::Post.new(url.path)
|
45
|
+
req.body = message
|
46
|
+
req["Content-Type"] = "Qnotifier-#{Qnotifier::VERSION}"
|
47
|
+
req["User-Agent"] = "application/json"
|
48
|
+
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
|
49
|
+
case res
|
50
|
+
when Net::HTTPSuccess
|
51
|
+
body = JSON.parse(res.body)
|
52
|
+
if body["poll_interval"]
|
53
|
+
@@poll_interval = body["poll_interval"].to_i
|
53
54
|
end
|
54
|
-
Qnotifier.log.debug "Server Response: HTTP #{response.code} #{body[:message]}"
|
55
55
|
else
|
56
|
-
Qnotifier.log.warn "Server Response: HTTP #{
|
56
|
+
Qnotifier.log.warn "Server Response: HTTP #{res.code} #{res.body}"
|
57
|
+
if res.code.to_i == 402
|
58
|
+
Qnotifier::Storage.put("server_disabled_pings", Time.now)
|
59
|
+
Qnotifier.log.error "Server has asked us to disable pings"
|
60
|
+
end
|
57
61
|
end
|
58
|
-
|
59
62
|
rescue Exception => e
|
60
|
-
Qnotifier.log.error "Sending
|
61
|
-
if e.message == "HTTP status code 402"
|
62
|
-
# The server doesn't want to hear from us any more, disable pinging
|
63
|
-
Qnotifier::Storage.put("server_disabled_pings", Time.now)
|
64
|
-
Qnotifier.log.error "Server has asked us to disable pings"
|
65
|
-
end
|
63
|
+
Qnotifier.log.error "Sending Alert: Can't connect to #{@config["api_endpoint"]} - #{e.message}"
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
@@ -72,11 +70,11 @@ module Qnotifier
|
|
72
70
|
last_run = Qnotifier::Storage.get("last_run")
|
73
71
|
if $qnotifier_debug
|
74
72
|
puts "\nStats:"
|
75
|
-
|
73
|
+
puts stats
|
76
74
|
puts "\nReports:"
|
77
|
-
|
75
|
+
puts reports
|
78
76
|
puts "\nNot sending data to server due to debug mode."
|
79
|
-
|
77
|
+
exit
|
80
78
|
end
|
81
79
|
if last_run and (Time.now - last_run) <= @@poll_interval
|
82
80
|
return
|
@@ -84,15 +82,16 @@ module Qnotifier
|
|
84
82
|
Qnotifier::Storage.put("last_run", Time.now)
|
85
83
|
|
86
84
|
return if reports.empty? and stats.empty?
|
87
|
-
Qnotifier.log.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
85
|
+
Qnotifier.log.debug "Sending Reports and Stats"
|
86
|
+
|
87
|
+
unless @hostname
|
88
|
+
unless @config["hostname"]
|
89
|
+
@hostname = `hostname`.strip
|
90
|
+
else
|
91
|
+
@hostname = @config["hostname"]
|
92
|
+
end
|
94
93
|
end
|
95
|
-
|
94
|
+
|
96
95
|
message = {"api_key" => @config["api_key"],
|
97
96
|
"api_version" => "1.0",
|
98
97
|
"agent_version" => Qnotifier::VERSION,
|
@@ -102,62 +101,55 @@ module Qnotifier
|
|
102
101
|
"reports" => reports}.to_json
|
103
102
|
|
104
103
|
begin
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
104
|
+
url = URI.parse("#{@config["api_endpoint"]}/update_server")
|
105
|
+
req = Net::HTTP::Post.new(url.path)
|
106
|
+
req.body = message
|
107
|
+
req["Content-Type"] = "Qnotifier-#{Qnotifier::VERSION}"
|
108
|
+
req["User-Agent"] = "application/json"
|
109
|
+
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
|
110
|
+
puts res.body
|
111
|
+
case res
|
112
|
+
when Net::HTTPSuccess
|
113
|
+
body = JSON.parse(res.body)
|
113
114
|
if body["poll_interval"]
|
114
|
-
|
115
|
-
#Qnotifier.log.info "Report polling interval is #{@@poll_interval}"
|
115
|
+
@@poll_interval = body["poll_interval"].to_i
|
116
116
|
end
|
117
|
-
Qnotifier.log.debug "Server Response: HTTP #{
|
117
|
+
Qnotifier.log.debug "Server Response: HTTP #{res.code} #{body[:message]}"
|
118
118
|
else
|
119
|
-
Qnotifier.log.warn "Server Response: HTTP #{
|
119
|
+
Qnotifier.log.warn "Server Response: HTTP #{res.code} #{res.body}"
|
120
|
+
if res.code.to_i == 402
|
121
|
+
puts "disabling pings"
|
122
|
+
Qnotifier::Storage.put("server_disabled_pings", Time.now)
|
123
|
+
Qnotifier.log.error "Server has asked us to disable pings"
|
124
|
+
end
|
120
125
|
end
|
121
|
-
|
122
126
|
rescue Exception => e
|
123
|
-
|
124
|
-
if e.message == "HTTP status code 402"
|
125
|
-
# The server doesn't want to hear from us any more, disable pinging
|
126
|
-
Qnotifier::Storage.put("server_disabled_pings", Time.now)
|
127
|
-
Qnotifier.log.error "Server has asked us to disable pings"
|
128
|
-
end
|
127
|
+
Qnotifier.log.error "Sending Reports/Stats: Can't connect to #{@config["api_endpoint"]} - #{e.message}"
|
129
128
|
end
|
130
129
|
end
|
131
130
|
|
132
131
|
def register_server(temp_key)
|
133
132
|
return if temp_key.empty?
|
134
|
-
Qnotifier.log.info "Registering Server"
|
135
|
-
|
136
|
-
message = {"temp_key" => temp_key, "hostname" => `hostname`.strip}.to_json
|
137
|
-
|
133
|
+
Qnotifier.log.info "Registering Server"
|
138
134
|
begin
|
139
|
-
puts "Connecting to the QNotifier web service..."
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
puts "Connecting to the QNotifier web service..."
|
136
|
+
url = URI.parse("#{@config["api_endpoint"]}/register_server")
|
137
|
+
req = Net::HTTP::Post.new(url.path)
|
138
|
+
req.body = {"temp_key" => temp_key, "hostname" => @hostname}.to_json
|
139
|
+
req["Content-Type"] = "Qnotifier-#{Qnotifier::VERSION}"
|
140
|
+
req["User-Agent"] = "application/json"
|
141
|
+
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
|
142
|
+
puts res.body
|
143
|
+
case res
|
144
|
+
when Net::HTTPSuccess
|
145
|
+
Qnotifier.log.debug "Registration Request Response: HTTP #{res.code} #{res.body}"
|
146
|
+
return res.body
|
148
147
|
else
|
149
|
-
Qnotifier.log.warn "Registration Request Response: HTTP #{
|
148
|
+
Qnotifier.log.warn "Registration Request Response: HTTP #{res.code} #{res.body}"
|
150
149
|
end
|
151
|
-
|
152
150
|
rescue Exception => e
|
153
|
-
|
154
|
-
puts "QNotifer web service: Can\'t find that code, please check it and try again.\n"
|
155
|
-
Qnotifier.log.error "QNotifer web service: Can\'t find that code, please check it and try again."
|
156
|
-
else
|
157
|
-
Qnotifier.log.error "Registering Server: Can't connect to #{@config["api_endpoint"]} - #{e.message}"
|
158
|
-
end
|
151
|
+
Qnotifier.log.error "Registering Server: Can't connect to #{@config["api_endpoint"]} - #{e.message}"
|
159
152
|
end
|
160
|
-
|
161
153
|
return nil
|
162
154
|
end
|
163
155
|
end
|
data/plugins/system.rb
CHANGED
@@ -36,9 +36,9 @@ module Qnotifier
|
|
36
36
|
when "one_minute"
|
37
37
|
load_average = load_one_minute
|
38
38
|
when "five_minute"
|
39
|
-
load_average =
|
39
|
+
load_average = load_five_minute
|
40
40
|
else
|
41
|
-
load_average =
|
41
|
+
load_average = load_fifteen_minute
|
42
42
|
end
|
43
43
|
|
44
44
|
report("Load", load_average)
|
@@ -130,7 +130,7 @@ module Qnotifier
|
|
130
130
|
Qnotifier.log.error "Can't parse /proc/stat"
|
131
131
|
end
|
132
132
|
else
|
133
|
-
Qnotifier.log.
|
133
|
+
Qnotifier.log.debug "Can't parse CPU for this platform - #{RUBY_PLATFORM}"
|
134
134
|
end
|
135
135
|
|
136
136
|
# Uname
|
@@ -166,7 +166,7 @@ module Qnotifier
|
|
166
166
|
end
|
167
167
|
|
168
168
|
else
|
169
|
-
Qnotifier.log.
|
169
|
+
Qnotifier.log.debug "Can't parse Memory for this platform - #{RUBY_PLATFORM}"
|
170
170
|
end
|
171
171
|
|
172
172
|
end
|
data/qnotifier.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{qnotifier}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "1.0.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Gersham Meharg"]
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.email = %q{gersham@qnotifier.com}
|
13
13
|
s.executables = ["qnotifier"]
|
14
14
|
s.extra_rdoc_files = ["bin/qnotifier", "lib/plugin.rb", "lib/qnotifier.rb", "lib/storage.rb", "lib/web_service.rb"]
|
15
|
-
s.files = ["Manifest", "Rakefile", "bin/qnotifier", "config/README", "config/qnotifier_config.yml", "gem-public_cert.pem", "lib/plugin.rb", "lib/qnotifier.rb", "lib/storage.rb", "lib/web_service.rb", "plugins/apache.rb", "plugins/mysql.rb", "plugins/
|
15
|
+
s.files = ["Manifest", "Rakefile", "bin/qnotifier", "config/README", "config/qnotifier_config.yml", "gem-public_cert.pem", "lib/plugin.rb", "lib/qnotifier.rb", "lib/storage.rb", "lib/web_service.rb", "plugins/apache.rb", "plugins/mysql.rb", "plugins/nginx.rb", "plugins/passenger.rb", "plugins/ruby.rb", "plugins/system.rb", "plugins/urls.rb", "init.d/qnotifier", "qnotifier.gemspec"]
|
16
16
|
s.homepage = %q{http://qnotifier.com/qnotifier_gem}
|
17
17
|
s.post_install_message = %q{Qnotifier installed, please register by running 'qnotifier' in order to register this server.}
|
18
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Qnotifier"]
|
@@ -28,24 +28,12 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.specification_version = 3
|
29
29
|
|
30
30
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
31
|
-
s.add_runtime_dependency(%q<
|
32
|
-
s.
|
33
|
-
s.add_runtime_dependency(%q<elif>, [">= 0.1.0"])
|
34
|
-
s.add_runtime_dependency(%q<robustthread>, [">= 0.5.2"])
|
35
|
-
s.add_development_dependency(%q<rest-client>, [">= 1.4.2"])
|
36
|
-
s.add_development_dependency(%q<json>, [">= 1.2.3"])
|
37
|
-
s.add_development_dependency(%q<elif>, [">= 0.1.0"])
|
38
|
-
s.add_development_dependency(%q<robustthread>, [">= 0.5.2"])
|
31
|
+
s.add_runtime_dependency(%q<json_pure>, [">= 1.2.3"])
|
32
|
+
s.add_development_dependency(%q<json_pure>, [">= 1.2.3"])
|
39
33
|
else
|
40
|
-
s.add_dependency(%q<
|
41
|
-
s.add_dependency(%q<json>, [">= 1.2.3"])
|
42
|
-
s.add_dependency(%q<elif>, [">= 0.1.0"])
|
43
|
-
s.add_dependency(%q<robustthread>, [">= 0.5.2"])
|
34
|
+
s.add_dependency(%q<json_pure>, [">= 1.2.3"])
|
44
35
|
end
|
45
36
|
else
|
46
|
-
s.add_dependency(%q<
|
47
|
-
s.add_dependency(%q<json>, [">= 1.2.3"])
|
48
|
-
s.add_dependency(%q<elif>, [">= 0.1.0"])
|
49
|
-
s.add_dependency(%q<robustthread>, [">= 0.5.2"])
|
37
|
+
s.add_dependency(%q<json_pure>, [">= 1.2.3"])
|
50
38
|
end
|
51
39
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -3,10 +3,10 @@ name: qnotifier
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
+
- 1
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 0.7.6
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Gersham Meharg
|
@@ -39,24 +39,9 @@ date: 2010-07-06 00:00:00 -07:00
|
|
39
39
|
default_executable: qnotifier
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: json_pure
|
43
43
|
prerelease: false
|
44
44
|
requirement: &id001 !ruby/object:Gem::Requirement
|
45
|
-
none: false
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
segments:
|
50
|
-
- 1
|
51
|
-
- 4
|
52
|
-
- 2
|
53
|
-
version: 1.4.2
|
54
|
-
type: :runtime
|
55
|
-
version_requirements: *id001
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: json
|
58
|
-
prerelease: false
|
59
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
60
45
|
none: false
|
61
46
|
requirements:
|
62
47
|
- - ">="
|
@@ -67,56 +52,11 @@ dependencies:
|
|
67
52
|
- 3
|
68
53
|
version: 1.2.3
|
69
54
|
type: :runtime
|
70
|
-
version_requirements: *
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: elif
|
73
|
-
prerelease: false
|
74
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
|
-
requirements:
|
77
|
-
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
segments:
|
80
|
-
- 0
|
81
|
-
- 1
|
82
|
-
- 0
|
83
|
-
version: 0.1.0
|
84
|
-
type: :runtime
|
85
|
-
version_requirements: *id003
|
86
|
-
- !ruby/object:Gem::Dependency
|
87
|
-
name: robustthread
|
88
|
-
prerelease: false
|
89
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
|
-
requirements:
|
92
|
-
- - ">="
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
segments:
|
95
|
-
- 0
|
96
|
-
- 5
|
97
|
-
- 2
|
98
|
-
version: 0.5.2
|
99
|
-
type: :runtime
|
100
|
-
version_requirements: *id004
|
101
|
-
- !ruby/object:Gem::Dependency
|
102
|
-
name: rest-client
|
103
|
-
prerelease: false
|
104
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ">="
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
segments:
|
110
|
-
- 1
|
111
|
-
- 4
|
112
|
-
- 2
|
113
|
-
version: 1.4.2
|
114
|
-
type: :development
|
115
|
-
version_requirements: *id005
|
55
|
+
version_requirements: *id001
|
116
56
|
- !ruby/object:Gem::Dependency
|
117
|
-
name:
|
57
|
+
name: json_pure
|
118
58
|
prerelease: false
|
119
|
-
requirement: &
|
59
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
120
60
|
none: false
|
121
61
|
requirements:
|
122
62
|
- - ">="
|
@@ -127,37 +67,7 @@ dependencies:
|
|
127
67
|
- 3
|
128
68
|
version: 1.2.3
|
129
69
|
type: :development
|
130
|
-
version_requirements: *
|
131
|
-
- !ruby/object:Gem::Dependency
|
132
|
-
name: elif
|
133
|
-
prerelease: false
|
134
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
135
|
-
none: false
|
136
|
-
requirements:
|
137
|
-
- - ">="
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
segments:
|
140
|
-
- 0
|
141
|
-
- 1
|
142
|
-
- 0
|
143
|
-
version: 0.1.0
|
144
|
-
type: :development
|
145
|
-
version_requirements: *id007
|
146
|
-
- !ruby/object:Gem::Dependency
|
147
|
-
name: robustthread
|
148
|
-
prerelease: false
|
149
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
|
-
requirements:
|
152
|
-
- - ">="
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
segments:
|
155
|
-
- 0
|
156
|
-
- 5
|
157
|
-
- 2
|
158
|
-
version: 0.5.2
|
159
|
-
type: :development
|
160
|
-
version_requirements: *id008
|
70
|
+
version_requirements: *id002
|
161
71
|
description: The server side agent for the QNotifier monitoring system. This software will monitor local Linux system parameters and upload them to the QNotifier servers where users can use iPhone/iPad applications to view those stats and recieve alerts.
|
162
72
|
email: gersham@qnotifier.com
|
163
73
|
executables:
|
@@ -183,10 +93,8 @@ files:
|
|
183
93
|
- lib/web_service.rb
|
184
94
|
- plugins/apache.rb
|
185
95
|
- plugins/mysql.rb
|
186
|
-
- plugins/network.rb
|
187
96
|
- plugins/nginx.rb
|
188
97
|
- plugins/passenger.rb
|
189
|
-
- plugins/rails.rb
|
190
98
|
- plugins/ruby.rb
|
191
99
|
- plugins/system.rb
|
192
100
|
- plugins/urls.rb
|
metadata.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
���r���>��Kk���S@��h�
|
2
|
+
�o굃��B�=� �u�1�Æ�o��hi[Ny��Q5[
|
data/plugins/network.rb
DELETED
data/plugins/rails.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require "elif"
|
3
|
-
|
4
|
-
module Qnotifier
|
5
|
-
class Rails < Qnotifier::Plugin
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@defaults = {
|
9
|
-
:rails_log_file => "/var/www/rails/log/production.log"
|
10
|
-
}
|
11
|
-
patch_elif
|
12
|
-
end
|
13
|
-
|
14
|
-
def main
|
15
|
-
Qnotifier.log.error "Rails plugin not yet supported in this beta version"
|
16
|
-
end
|
17
|
-
|
18
|
-
def patch_elif
|
19
|
-
if Elif::VERSION < "0.2.0"
|
20
|
-
Elif.send(:define_method, :pos) do
|
21
|
-
@current_pos +
|
22
|
-
@line_buffer.inject(0) { |bytes, line| bytes + line.size }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def read_backwards_to_timestamp(path, timestamp)
|
28
|
-
start = nil
|
29
|
-
Elif.open(path) do |elif|
|
30
|
-
elif.each do |line|
|
31
|
-
if line =~ /\AProcessing .+ at (\d+-\d+-\d+ \d+:\d+:\d+)\)/
|
32
|
-
time_of_request = Time.parse($1)
|
33
|
-
if time_of_request < timestamp
|
34
|
-
break
|
35
|
-
else
|
36
|
-
start = elif.pos
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
file = open(path)
|
43
|
-
file.seek(start) if start
|
44
|
-
file
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|