qnotifier 0.7.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|