lennartkoopmann-scopeport-client-ruby 0.0.4 → 0.1.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/VERSION +1 -1
- data/bin/scopeport-client +241 -51
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/scopeport-client
CHANGED
@@ -17,29 +17,128 @@
|
|
17
17
|
# You should have received a copy of the GNU General Public License
|
18
18
|
# along with ScopePort (Client Ruby). If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
|
20
|
-
puts "Starting up (Ruby #{RUBY_VERSION} #{RUBY_PLATFORM})"
|
21
|
-
|
22
20
|
require "socket"
|
21
|
+
require "optparse"
|
22
|
+
|
23
|
+
$hostname = "localhost"
|
24
|
+
$port = 12200
|
25
|
+
$host_id = 1
|
26
|
+
$password = "secret"
|
27
|
+
|
28
|
+
$system = "linux"
|
29
|
+
case $system
|
30
|
+
when "linux": $log_directory = "/var/log/"
|
31
|
+
end
|
32
|
+
|
33
|
+
$logfile = "#{$log_directory}scopeport-client.log"
|
23
34
|
|
24
|
-
|
25
|
-
port = 12200
|
26
|
-
host_id = 1
|
27
|
-
password = "secret"
|
35
|
+
Version = "0.0.5"
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
def clean_up
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
|
41
|
+
# Signal handling
|
42
|
+
trap "INT" do clean_up end
|
43
|
+
trap "ABRT" do clean_up end
|
44
|
+
trap "FPE" do clean_up end
|
45
|
+
trap "ILL" do clean_up end
|
46
|
+
trap "SEGV" do clean_up end
|
47
|
+
trap "TERM" do clean_up end
|
48
|
+
|
49
|
+
class LinuxSensor
|
50
|
+
protected
|
51
|
+
def poll_sensor_cpu_load_average averaged_time
|
52
|
+
begin
|
53
|
+
file = File.open "/proc/loadavg", "r"
|
54
|
+
data = file.readline
|
55
|
+
file.close
|
56
|
+
parts = data.split " "
|
57
|
+
case averaged_time
|
58
|
+
when 1: return parts[0]
|
59
|
+
when 5: return parts[1]
|
60
|
+
when 15: return parts[2]
|
61
|
+
end
|
62
|
+
rescue => e
|
63
|
+
Log::put_log "Could not measure CPU load average #{averaged_time}: #{e}"
|
64
|
+
return "-0-"
|
65
|
+
end
|
66
|
+
return "-0-"
|
67
|
+
end
|
68
|
+
|
69
|
+
def poll_sensor_open_files
|
70
|
+
begin
|
71
|
+
file = File.open "/proc/sys/fs/file-nr", "r"
|
72
|
+
data = file.readline
|
73
|
+
file.close
|
74
|
+
parts = data.split " "
|
75
|
+
return parts[0]
|
76
|
+
rescue => e
|
77
|
+
Log::put_log "Could not measure currently opened files: #{e}"
|
78
|
+
return "-0-"
|
79
|
+
end
|
80
|
+
return "-0-"
|
81
|
+
end
|
31
82
|
|
32
|
-
|
83
|
+
def poll_sensor_maximum_open_files
|
84
|
+
begin
|
85
|
+
file = File.open "/proc/sys/fs/file-max", "r"
|
86
|
+
data = file.readline
|
87
|
+
file.close
|
88
|
+
return data
|
89
|
+
rescue => e
|
90
|
+
Log::put_log "Could not measure defined maximum of opened files: #{e}"
|
91
|
+
return "-0-"
|
92
|
+
end
|
93
|
+
return "-0-"
|
94
|
+
end
|
95
|
+
|
96
|
+
def poll_sensor_running_processes
|
97
|
+
begin
|
98
|
+
file = File.open "/proc/loadavg", "r"
|
99
|
+
data = file.readline
|
100
|
+
file.close
|
101
|
+
parts = data.split " "
|
102
|
+
procs = parts[3].split "/"
|
103
|
+
return procs[0]
|
104
|
+
rescue => e
|
105
|
+
Log::put_log "Could not measure currently running processes: #{e}"
|
106
|
+
return "-0-"
|
107
|
+
end
|
108
|
+
return "-0-"
|
109
|
+
end
|
110
|
+
|
111
|
+
def poll_sensor_total_processes
|
112
|
+
begin
|
113
|
+
file = File.open "/proc/loadavg", "r"
|
114
|
+
data = file.readline
|
115
|
+
file.close
|
116
|
+
parts = data.split " "
|
117
|
+
procs = parts[3].split "/"
|
118
|
+
return procs[1]
|
119
|
+
rescue => e
|
120
|
+
Log::put_log "Could not measure total number of processes: #{e}"
|
121
|
+
return "-0-"
|
122
|
+
end
|
123
|
+
return "-0-"
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
class Sensor < LinuxSensor
|
33
129
|
public
|
34
130
|
def initialize sensor_name
|
35
131
|
@@name = sensor_name
|
36
|
-
@@value = ""
|
37
132
|
end
|
38
133
|
|
39
134
|
def self.get_sensor_names
|
40
|
-
return [ "
|
41
|
-
"
|
42
|
-
"
|
135
|
+
return [ "cpu_load_average_1", # CPU load average last minute
|
136
|
+
"cpu_load_average_5", # CPU load average last five minutes
|
137
|
+
"cpu_load_average_15", # CPU load average last fifteen minutes
|
138
|
+
"open_files", # Currently opened files
|
139
|
+
"maximum_open_files", # Configured maximum of opened files
|
140
|
+
"running_processes", # Currently running processes
|
141
|
+
"total_processes" # Total number of processes
|
43
142
|
]
|
44
143
|
end
|
45
144
|
|
@@ -48,10 +147,23 @@ class Sensor
|
|
48
147
|
end
|
49
148
|
|
50
149
|
def value
|
51
|
-
|
150
|
+
begin
|
151
|
+
case @@name
|
152
|
+
when "cpu_load_average_1": return poll_sensor_cpu_load_average 1
|
153
|
+
when "cpu_load_average_5": return poll_sensor_cpu_load_average 5
|
154
|
+
when "cpu_load_average_15": return poll_sensor_cpu_load_average 15
|
155
|
+
when "open_files": return poll_sensor_open_files
|
156
|
+
when "maximum_open_files": return poll_sensor_maximum_open_files
|
157
|
+
when "running_processes": return poll_sensor_running_processes
|
158
|
+
when "total_processes": return poll_sensor_total_processes
|
159
|
+
end
|
160
|
+
rescue
|
161
|
+
return "-0-"
|
162
|
+
end
|
163
|
+
return "-0-"
|
52
164
|
end
|
53
165
|
|
54
|
-
|
166
|
+
end
|
55
167
|
|
56
168
|
class Conversation
|
57
169
|
public
|
@@ -83,7 +195,7 @@ class Conversation
|
|
83
195
|
def login host_id, password
|
84
196
|
begin
|
85
197
|
login_message = "#{host_id},login,#{password}"
|
86
|
-
@@socket.send login_message,
|
198
|
+
@@socket.send login_message, 0
|
87
199
|
msg = @@socket.recvfrom 100
|
88
200
|
raise "Empty or no reply" if msg[0].length == 0
|
89
201
|
raise msg[0] if msg[0] != "Okay"
|
@@ -99,8 +211,8 @@ class Conversation
|
|
99
211
|
raise "Illegal characters" if sensor.include? "," or value.include? ","
|
100
212
|
|
101
213
|
begin
|
102
|
-
sensor_message = "#{host_id},#{sensor},#{value}"
|
103
|
-
@@socket.send sensor_message,
|
214
|
+
sensor_message = "#{host_id},#{sensor},#{value}".chomp
|
215
|
+
@@socket.send sensor_message, 0
|
104
216
|
msg = @@socket.recvfrom 100
|
105
217
|
raise "Empty or no reply" if msg[0].length == 0
|
106
218
|
raise msg[0] if msg[0] != "Okay"
|
@@ -110,43 +222,121 @@ class Conversation
|
|
110
222
|
end
|
111
223
|
end
|
112
224
|
|
113
|
-
|
225
|
+
class Log
|
226
|
+
def self.put_log message
|
227
|
+
if File.exists? $logfile and File.writable? $logfile
|
228
|
+
file = File.open $logfile, "a"
|
229
|
+
file.puts "#{Time.now}: #{message}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
114
233
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
234
|
+
# Check if the logfile exists
|
235
|
+
if !File.exists? $logfile
|
236
|
+
puts "Warning: Logfile (#{$logfile}) does not exist."
|
237
|
+
else
|
238
|
+
# The logfile exists. Check if it is writable
|
239
|
+
if !File.writable? $logfile
|
240
|
+
puts "Warning: Logfile (#{$logfile}) is not writable."
|
122
241
|
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def run
|
245
|
+
puts "Starting up (Ruby #{RUBY_VERSION} #{RUBY_PLATFORM})"
|
246
|
+
system_info = `uname -snrm`.chop
|
247
|
+
puts "Loaded sensor definition file GNU/Linux (#{system_info})"
|
248
|
+
|
249
|
+
while 1 do
|
250
|
+
# Get every sensor and sent it's value.
|
251
|
+
sensor_names = Sensor::get_sensor_names
|
252
|
+
sensor_names.each do |sensor_name|
|
123
253
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
254
|
+
# Connect to the ScopePort server.
|
255
|
+
begin
|
256
|
+
con = Conversation.new $hostname, $port
|
257
|
+
rescue => e
|
258
|
+
Log::put_log "Could not connect to ScopePort server: #{e}"
|
259
|
+
sleep(5)
|
260
|
+
next
|
261
|
+
end
|
262
|
+
|
263
|
+
# Log in
|
264
|
+
begin
|
265
|
+
con.login $host_id, $password
|
266
|
+
rescue => e
|
267
|
+
Log::put_log "Could not log in: #{e}"
|
268
|
+
con.close
|
269
|
+
sleep(5)
|
270
|
+
next
|
271
|
+
end
|
272
|
+
|
273
|
+
# Send sensor data
|
274
|
+
begin
|
275
|
+
sensor = Sensor.new sensor_name
|
276
|
+
con.send_sensor_data $host_id, sensor.name, sensor.value
|
277
|
+
rescue => e
|
278
|
+
Log::put_log "Could not send sensor data: #{e}"
|
279
|
+
end
|
280
|
+
|
281
|
+
# All done. Close socket.
|
282
|
+
con.close
|
283
|
+
end
|
284
|
+
|
285
|
+
sleep 60
|
132
286
|
end
|
287
|
+
end
|
133
288
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# # Send sensor data
|
141
|
-
# begin
|
142
|
-
# con.send_sensor_data host_id, sensor["name"], sensor["value"]
|
143
|
-
# rescue => e
|
144
|
-
# puts "Could not send sensor data: #{e}"
|
145
|
-
# end
|
289
|
+
# Parse shell parameters
|
290
|
+
options = {}
|
291
|
+
opts = OptionParser.new do |opts|
|
292
|
+
opts.on "--start" do
|
293
|
+
# Requested action: Start the ScopePort client.
|
294
|
+
run
|
146
295
|
end
|
147
|
-
|
148
|
-
# All done. Close socket.
|
149
|
-
con.close
|
150
296
|
|
151
|
-
|
152
|
-
|
297
|
+
opts.on "--stop" do
|
298
|
+
# Requested action: Stop the ScopePort client.
|
299
|
+
`killall scopeport-client`
|
300
|
+
exit
|
301
|
+
end
|
302
|
+
|
303
|
+
opts.on "-t", "--test-sensors" do
|
304
|
+
# Requested action: Show all sensors with their values.
|
305
|
+
sensor_names = Sensor::get_sensor_names
|
306
|
+
puts "#{sensor_names.count} sensors supported by this version (#{Version}):"
|
307
|
+
sensor_names.each do |sensor_name|
|
308
|
+
sensor = Sensor.new sensor_name
|
309
|
+
puts "\tSensor #{sensor.name} has value #{sensor.value}"
|
310
|
+
end
|
311
|
+
exit
|
312
|
+
end
|
313
|
+
|
314
|
+
opts.on "-v", "--version" do
|
315
|
+
# Requested action: Show the version
|
316
|
+
puts "ScopePort Client v.#{Version}"
|
317
|
+
puts "Ruby #{RUBY_VERSION} #{RUBY_PLATFORM}"
|
318
|
+
system_info = `uname -snrm`.chop
|
319
|
+
puts "System: #{system_info}"
|
320
|
+
exit
|
321
|
+
end
|
322
|
+
|
323
|
+
opts.on "-h", "--help" do
|
324
|
+
# Requested action: Show the help message
|
325
|
+
puts "== Description"
|
326
|
+
puts "\t This is the ScopePort client. This program collects system information and sends it to a ScopePort server installation."
|
327
|
+
puts "== Configuration"
|
328
|
+
puts "\t The configuration takes place in /etc/scopeport/scopeport-client.conf"
|
329
|
+
puts "== Example"
|
330
|
+
puts "\t scopeport-client --start"
|
331
|
+
puts "== Parameters"
|
332
|
+
puts "\t --start: Start the client"
|
333
|
+
puts "\t --stop: Stop the client. Kills all scopeport-client processes on this machine"
|
334
|
+
puts "\t -h, --help: Print this help message"
|
335
|
+
puts "\t -t, --test-sensors: Print all sensors with their current value"
|
336
|
+
puts "\t -v, --version: Print the version"
|
337
|
+
exit
|
338
|
+
end
|
339
|
+
end.parse!
|
340
|
+
|
341
|
+
# This is shown if no matching command line parameter was given
|
342
|
+
puts "Usage: scopeport-client --start/--stop or --help for more information"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lennartkoopmann-scopeport-client-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lennart Koopmann
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -25,6 +25,7 @@ files:
|
|
25
25
|
- VERSION
|
26
26
|
has_rdoc: false
|
27
27
|
homepage: http://www.scopeport.org/
|
28
|
+
licenses:
|
28
29
|
post_install_message:
|
29
30
|
rdoc_options:
|
30
31
|
- --charset=UTF-8
|
@@ -45,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
46
|
requirements: []
|
46
47
|
|
47
48
|
rubyforge_project:
|
48
|
-
rubygems_version: 1.
|
49
|
+
rubygems_version: 1.3.5
|
49
50
|
signing_key:
|
50
51
|
specification_version: 2
|
51
52
|
summary: TODO
|