oml4r 2.9.10 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/oml4r-multiple-channel-example +81 -0
- data/bin/oml4r-neuca-beacon +52 -0
- data/bin/oml4r-orca-beacon +56 -0
- data/bin/oml4r-simple-example +66 -0
- data/bin/oml4r-solar +74 -0
- data/bin/oml4r-wlanconfig +151 -0
- data/bin/oml4r-zabbix +98 -0
- data/bin/test_types +45 -0
- data/examples/oml4r-multiple-channel-example.rb +0 -0
- data/examples/oml4r-neuca-beacon.rb +0 -0
- data/examples/oml4r-simple-example.rb +4 -0
- data/examples/oml4r-solar.rb +1 -1
- data/examples/oml4r-wlanconfig.rb +0 -0
- data/examples/oml4r-zabbix.rb +0 -0
- data/examples/test_types.rb +2 -0
- data/lib/oml4r/version.rb +1 -1
- data/lib/oml4r.rb +74 -31
- data/oml4r.gemspec +1 -0
- metadata +25 -8
- checksums.yaml +0 -15
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright (c) 2013 National ICT Australia Limited (NICTA).
|
4
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
5
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
6
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
7
|
+
# ------------------
|
8
|
+
#
|
9
|
+
# = oml4r-multiple-channel-example.rb
|
10
|
+
#
|
11
|
+
# == Description
|
12
|
+
#
|
13
|
+
# An extension of the 'oml4r-simple.example.rb' example demonstrating the use of
|
14
|
+
# multiple destinations for different measurements.
|
15
|
+
#
|
16
|
+
# == Usage
|
17
|
+
#
|
18
|
+
# The following write the COS measurements to STDOUT (file:-) and the SIN
|
19
|
+
# measurements to /tmp/ch2.oml (which can be overwrriten with the --oml-ch2 option)
|
20
|
+
#
|
21
|
+
# % cd $OML_HOME
|
22
|
+
# % ruby -I lib examples/oml4r-multiple-channel-example.rb --oml-ch1 file:-
|
23
|
+
#
|
24
|
+
# Use --oml-help to get all available options
|
25
|
+
#
|
26
|
+
# % cd $OML_HOME
|
27
|
+
# % ruby -I lib examples/oml4r-multiple-channel-example.rb --oml-help
|
28
|
+
#
|
29
|
+
require 'rubygems'
|
30
|
+
require 'oml4r'
|
31
|
+
|
32
|
+
# Define your own Measurement Points
|
33
|
+
class SinMP < OML4R::MPBase
|
34
|
+
name :sin
|
35
|
+
channel :ch1
|
36
|
+
|
37
|
+
param :label
|
38
|
+
param :angle, :type => :int32
|
39
|
+
param :value, :type => :double
|
40
|
+
end
|
41
|
+
|
42
|
+
class CosMP < OML4R::MPBase
|
43
|
+
name :cos
|
44
|
+
channel :ch2
|
45
|
+
|
46
|
+
param :label
|
47
|
+
param :value, :type => :double
|
48
|
+
end
|
49
|
+
|
50
|
+
# Initialise the OML4R module for your application
|
51
|
+
opts = {
|
52
|
+
:appName => 'oml4rSimpleExample',
|
53
|
+
:domain => 'foo',
|
54
|
+
:create_default_channel => false # we don't need the default channel
|
55
|
+
}
|
56
|
+
#
|
57
|
+
ch1 = OML4R::create_channel(:ch1, 'file:/tmp/ch1.oml')
|
58
|
+
ch2 = OML4R::create_channel(:ch2, 'file:/tmp/ch2.oml')
|
59
|
+
|
60
|
+
begin
|
61
|
+
OML4R::init(ARGV, opts) do |op|
|
62
|
+
op.on("--oml-ch1 URL", "Set destination for Channel 1 [#{ch1.url}]") { |url| ch1.url = url }
|
63
|
+
op.on("--oml-ch2 URL", "Set destination for Channel 2 [#{ch2.url}]") { |url| ch2.url = url }
|
64
|
+
end
|
65
|
+
rescue OML4R::MissingArgumentException => mex
|
66
|
+
$stderr.puts mex
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
|
70
|
+
# Now collect and inject some measurements
|
71
|
+
500.times do |i|
|
72
|
+
sleep 0.5
|
73
|
+
angle = 15 * i
|
74
|
+
SinMP.inject("label_#{angle}", angle, Math.sin(angle))
|
75
|
+
CosMP.inject("label_#{angle}", Math.cos(angle))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Don't forget to close when you are finished
|
79
|
+
OML4R::close()
|
80
|
+
|
81
|
+
# vim: sw=2
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Observes network connectivity on ExoGENI slices
|
4
|
+
# Sends UDP broadcast messages and reports incoming messages via OML
|
5
|
+
# (including its own) to build a connectivity graph
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'eventmachine'
|
9
|
+
require 'oml4r'
|
10
|
+
require 'parseconfig'
|
11
|
+
|
12
|
+
port = 9089
|
13
|
+
interval = 10
|
14
|
+
neuca_file = "/tmp/neuca-user-data.txt"
|
15
|
+
|
16
|
+
abort "Could not run 'neuca-user-data'" if !`neuca-user-data > #{neuca_file}`
|
17
|
+
neuca_user_data = ParseConfig.new(neuca_file)['global']
|
18
|
+
|
19
|
+
class MyMP < OML4R::MPBase
|
20
|
+
name :received
|
21
|
+
param :actor_id, :type => :string
|
22
|
+
param :slice_id, :type => :string
|
23
|
+
param :reservation_id, :type => :string
|
24
|
+
param :unit_id, :type => :string
|
25
|
+
end
|
26
|
+
|
27
|
+
oml_opts = {:appName => 'beacon', :domain => neuca_user_data['slice_id'],
|
28
|
+
:nodeID => neuca_user_data['unit_id'], :collect => 'file:-'}
|
29
|
+
|
30
|
+
node = OML4R::init(ARGV, oml_opts) do |op|
|
31
|
+
op.banner = "Usage: #{$0} [options]\n"
|
32
|
+
op.on( '-i', '--interval n', "Send UDP broadcast beacon every n seconds [#{interval}]" ) do |i|
|
33
|
+
interval = i.to_i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ServerSocket
|
38
|
+
def receive_data data
|
39
|
+
d=eval(data)
|
40
|
+
return if d.class != Hash
|
41
|
+
MyMP.inject(d['actor_id'], d['slice_id'], d['reservation_id'], d['unit_id'])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
EventMachine.run {
|
46
|
+
socket = EventMachine.open_datagram_socket "0.0.0.0", port, ServerSocket
|
47
|
+
EventMachine.add_periodic_timer(interval) {
|
48
|
+
socket.send_datagram(neuca_user_data, "255.255.255.255", port)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
OML4R::close()
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Observes network connectivity on ORCA slices
|
4
|
+
# Sends UDP broadcast messages and reports incoming messages via OML
|
5
|
+
# (including its own) to build a connectivity graph
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'eventmachine'
|
9
|
+
require 'oml4r'
|
10
|
+
require 'system/getifaddrs'
|
11
|
+
|
12
|
+
port = 9089
|
13
|
+
interval = 10
|
14
|
+
ip_addresses = []
|
15
|
+
NAME = ENV['OML_ID']
|
16
|
+
oml_opts = {:appName => 'beacon', :collect => 'file:-'}
|
17
|
+
|
18
|
+
abort "Please set the OML_ID environment variable" if NAME.nil?
|
19
|
+
|
20
|
+
System.get_ifaddrs.each do |ip|
|
21
|
+
# don't report IP address of loopback interface
|
22
|
+
next if ip[0]==:lo
|
23
|
+
ip_addresses << ip[1][:inet_addr]
|
24
|
+
end
|
25
|
+
|
26
|
+
class MyMP < OML4R::MPBase
|
27
|
+
name :received
|
28
|
+
param :receiver_name, :type => :string
|
29
|
+
param :sender_name, :type => :string
|
30
|
+
param :ip_addresses, :type => :string
|
31
|
+
end
|
32
|
+
|
33
|
+
OML4R::init(ARGV, oml_opts) do |op|
|
34
|
+
op.banner = "Usage: #{$0} [options]\n"
|
35
|
+
op.on( '-i', '--interval n', "Send UDP broadcast beacon every n seconds [#{interval}]" ) do |i|
|
36
|
+
interval = i.to_i
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ServerSocket
|
41
|
+
def receive_data data
|
42
|
+
d=eval(data)
|
43
|
+
return if d.class != Hash
|
44
|
+
# don't log my own beacons
|
45
|
+
MyMP.inject(NAME, d[:sender_name], d[:ip_addresses]) if NAME != d[:sender_name]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
EventMachine.run {
|
50
|
+
socket = EventMachine.open_datagram_socket "0.0.0.0", port, ServerSocket
|
51
|
+
EventMachine.add_periodic_timer(interval) {
|
52
|
+
socket.send_datagram({:sender_name => NAME, :ip_addresses=> ip_addresses.join(' ')}, "255.255.255.255", port)
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
OML4R::close()
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright (c) 2009 - 2012 National ICT Australia Limited (NICTA).
|
4
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
5
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
6
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
7
|
+
# ------------------
|
8
|
+
#
|
9
|
+
# = oml4r-simple-example.rb
|
10
|
+
#
|
11
|
+
# == Description
|
12
|
+
#
|
13
|
+
# A very simple straightforward example of OML4R.
|
14
|
+
#
|
15
|
+
|
16
|
+
# Use the oml4r.rb from ../lib
|
17
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'oml4r'
|
21
|
+
|
22
|
+
# Define your own Measurement Points
|
23
|
+
class SinMP < OML4R::MPBase
|
24
|
+
name :sin
|
25
|
+
#channel :default
|
26
|
+
|
27
|
+
param :label
|
28
|
+
param :angle, :type => :int32
|
29
|
+
param :value, :type => :double
|
30
|
+
end
|
31
|
+
|
32
|
+
class CosMP < OML4R::MPBase
|
33
|
+
name :cos
|
34
|
+
# channel :ch1
|
35
|
+
# channel :default
|
36
|
+
|
37
|
+
param :label
|
38
|
+
param :value, :type => :double
|
39
|
+
end
|
40
|
+
|
41
|
+
# Initialise the OML4R module for your application
|
42
|
+
opts = {:appName => 'oml4rSimpleExample',
|
43
|
+
:domain => 'foo',
|
44
|
+
:collect => 'file:-'} # Server could also be tcp:host:port
|
45
|
+
#
|
46
|
+
#OML4R::create_channel(:ch1, 'file:/tmp/foo.log')
|
47
|
+
|
48
|
+
begin
|
49
|
+
OML4R::init(ARGV, opts)
|
50
|
+
rescue OML4R::MissingArgumentException => mex
|
51
|
+
$stderr.puts mex
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
|
55
|
+
# Now collect and inject some measurements
|
56
|
+
500.times do |i|
|
57
|
+
sleep 0.5
|
58
|
+
angle = 15 * i
|
59
|
+
SinMP.inject("label_#{angle}", angle, Math.sin(angle))
|
60
|
+
CosMP.inject("label_#{angle}", Math.cos(angle))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Don't forget to close when you are finished
|
64
|
+
OML4R::close()
|
65
|
+
|
66
|
+
# vim: sw=2
|
data/bin/oml4r-solar
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'oml4r'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'open-uri'
|
7
|
+
|
8
|
+
# collects live solar power production data from the front page
|
9
|
+
# of the SMA 'Sunny Webbox' plant management web interface
|
10
|
+
# and inserts it into OML
|
11
|
+
|
12
|
+
def convert_to_W(p)
|
13
|
+
a=p.split(" ")
|
14
|
+
case a[1]
|
15
|
+
when "W"
|
16
|
+
return a[0].to_f
|
17
|
+
when "kW", "kWh"
|
18
|
+
return a[0].to_f*1000
|
19
|
+
when "MW", "MWh"
|
20
|
+
return a[0].to_f*1000000
|
21
|
+
when "GW", "GWh"
|
22
|
+
# 1.21 gigawatts!!
|
23
|
+
return a[0].to_f*1000000000
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Define your own Measurement Point
|
28
|
+
class MyMP < OML4R::MPBase
|
29
|
+
name :Power
|
30
|
+
param :ts, :type => :string
|
31
|
+
param :Now_W, :type => :double
|
32
|
+
param :DailyYield_Wh, :type => :double
|
33
|
+
param :TotalYield_Wh, :type => :double
|
34
|
+
end
|
35
|
+
|
36
|
+
# poll every second by default
|
37
|
+
interval = 1
|
38
|
+
host = nil
|
39
|
+
|
40
|
+
# Initialise the OML4R module for your application
|
41
|
+
oml_opts = {:appName => 'webbox',
|
42
|
+
:domain => 'webbox-solar-live', :nodeID => 'plant1',
|
43
|
+
:collect => 'file:-'}
|
44
|
+
|
45
|
+
node = OML4R::init(ARGV, oml_opts) do |op|
|
46
|
+
op.banner = "Usage: #{$0} [options] webbox_ip_addr ...\n"
|
47
|
+
op.on( '-i', '--interval SEC', "Query interval in seconds [#{interval}]" ) do |i|
|
48
|
+
interval = i.to_i
|
49
|
+
end
|
50
|
+
op.on( '-w', '--webbox HOST', "Hostname or IP address of Sunny Webbox" ) do |w|
|
51
|
+
host = w
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
abort "Please specify the hostname or IP address of the Sunny Webbox ('-w')." if host.nil?
|
56
|
+
|
57
|
+
# catch CTRL-C
|
58
|
+
exit_requested = false
|
59
|
+
Kernel.trap( "INT" ) { exit_requested = true }
|
60
|
+
|
61
|
+
# poll Sunny Webbox
|
62
|
+
while !exit_requested
|
63
|
+
doc = Nokogiri::HTML(open("http://#{host}/home.htm"))
|
64
|
+
p=convert_to_W(doc.xpath('//td[@id="Power"]').text)
|
65
|
+
d=convert_to_W(doc.xpath('//td[@id="DailyYield"]').text)
|
66
|
+
t=convert_to_W(doc.xpath('//td[@id="TotalYield"]').text)
|
67
|
+
# do not collect data when no power is generated
|
68
|
+
next if p==0
|
69
|
+
# inject the measurements
|
70
|
+
MyMP.inject(Time.now,p,d,t)
|
71
|
+
sleep interval
|
72
|
+
end
|
73
|
+
|
74
|
+
OML4R::close()
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright (c) 2010-2013 National ICT Australia (NICTA), Australia
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
#
|
24
|
+
# = oml4r-wlanconfig.rb
|
25
|
+
#
|
26
|
+
# == Description
|
27
|
+
#
|
28
|
+
# This is a simple example on how to use the OML4R module to create a simple
|
29
|
+
# ruby application that "wraps" around the existing command "wlanconfig".
|
30
|
+
# This wrapper invokes "wlanconfig" at regular interval, captures and formats
|
31
|
+
# its output (= measurements), and finally pass them to OML4R, which will in
|
32
|
+
# turn either store them in a local file or forward them to the OML Server.
|
33
|
+
#
|
34
|
+
require "rubygems"
|
35
|
+
require "oml4r"
|
36
|
+
|
37
|
+
APPNAME = "wlanconfig"
|
38
|
+
APPPATH = "/sbin/wlanconfig"
|
39
|
+
|
40
|
+
|
41
|
+
#
|
42
|
+
# This class defines the Measurement Point for our application and the
|
43
|
+
# corresponding metrics we would like to capture
|
44
|
+
#
|
45
|
+
class WlanConfigMP < OML4R::MPBase
|
46
|
+
name :wlanstat
|
47
|
+
param :addr
|
48
|
+
param :aid, :type => :int32
|
49
|
+
param :channel, :type => :int32
|
50
|
+
param :rate
|
51
|
+
param :rssi, :type => :int32
|
52
|
+
param :dbm, :type => :int32
|
53
|
+
param :idle, :type => :int32
|
54
|
+
param :txseq, :type => :int32
|
55
|
+
param :rxseq, :type => :int32
|
56
|
+
# Note: other metrics potentially returned by wlanconfig are
|
57
|
+
# not supported here, as they are seldom set by wlanconfig.
|
58
|
+
# These are: caps, acaps, erp, mode
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# This class is the Wrapper around the existing "wlanconfig" application
|
63
|
+
#
|
64
|
+
class Wrapper
|
65
|
+
|
66
|
+
#
|
67
|
+
# Initialise a new Wrapper object
|
68
|
+
# - args = the command line argument which was given to this wrapper
|
69
|
+
# application
|
70
|
+
#
|
71
|
+
def initialize(args)
|
72
|
+
|
73
|
+
# Initialise some variable specific to this wrapper
|
74
|
+
@interface = nil
|
75
|
+
@interval = 1
|
76
|
+
|
77
|
+
# Now call the Init of OML4R with the command line arguments (args)
|
78
|
+
# and a block defining the arguments specific to this wrapper
|
79
|
+
OML4R::init(args, :appName => "#{APPNAME}_wrapper", :domain => 'foo', :collect => 'file:-') { |argParser|
|
80
|
+
argParser.banner = "\nExecute a wrapper around #{APPNAME}\n" +
|
81
|
+
"Use -h or --help for a list of options\n\n"
|
82
|
+
argParser.on("-i", "--interface IFNAME", "Name of Interface to monitor") { |name| @interface = name }
|
83
|
+
argParser.on("-s", "--sampling DURATION", "Interval in second between sample collection for OML") { |time| @interval = time }
|
84
|
+
}
|
85
|
+
|
86
|
+
# Finally do some checking specific to this wrapper
|
87
|
+
# e.g. here we do not proceed if the user did not give us a
|
88
|
+
# valid interface to monitor
|
89
|
+
unless @interface != nil
|
90
|
+
raise "You did not specify an interface to monitor! (-i option)"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Start the wrapped "wlaconfig" application, capture and process its output
|
96
|
+
#
|
97
|
+
def start()
|
98
|
+
# Loop until the user interrupts us
|
99
|
+
while true
|
100
|
+
# Run the wlanconfig command
|
101
|
+
cmd = "#{APPPATH} #{@interface} list"
|
102
|
+
output = `#{cmd}`
|
103
|
+
# Process its output
|
104
|
+
processOutput(output)
|
105
|
+
# Wait for a given duration and loop again
|
106
|
+
sleep @interval.to_i
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Process each output coming from an executing of the "wlaconfig" application
|
112
|
+
# - output = a String holding the output to process
|
113
|
+
#
|
114
|
+
def processOutput(output)
|
115
|
+
# wlanconfig returns a sequence of lines
|
116
|
+
# The 1st line is a list of labels for the fields of the remaining lines
|
117
|
+
# Each remaining line is for a given station, and follow the format:
|
118
|
+
# ADDR AID CHAN RATE RSSI DBM IDLE TXSEQ RXSEQ CAPS ACAPS ERP STATE MODE
|
119
|
+
lines = output.split("\n")
|
120
|
+
labels = lines.delete_at(0)
|
121
|
+
lines.each { |row|
|
122
|
+
column = row.split(" ")
|
123
|
+
# Inject the measurements into OML
|
124
|
+
WlanConfigMP.inject("#{column[0]}", column[1], column[2],
|
125
|
+
"#{column[3]}", column[4], column[5],
|
126
|
+
column[6], column[7], column[8])
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Entry point to this Ruby application
|
135
|
+
#
|
136
|
+
begin
|
137
|
+
app = Wrapper.new(ARGV)
|
138
|
+
app.start()
|
139
|
+
rescue SystemExit
|
140
|
+
rescue SignalException
|
141
|
+
puts "Wrapper stopped."
|
142
|
+
rescue Exception => ex
|
143
|
+
puts "Error - When executing the wrapper application!"
|
144
|
+
puts "Error - Type: #{ex.class}"
|
145
|
+
puts "Error - Message: #{ex}\n\n"
|
146
|
+
# Uncomment the next line to get more info on errors
|
147
|
+
# puts "Trace - #{ex.backtrace.join("\n\t")}"
|
148
|
+
end
|
149
|
+
OML4R::close()
|
150
|
+
|
151
|
+
# vim: sw=2
|
data/bin/oml4r-zabbix
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# example script that reads CPU load measurements from a Zabbix server
|
4
|
+
# and pushes them into an OML database
|
5
|
+
|
6
|
+
# make sure you install these two gems
|
7
|
+
require "zabbixapi"
|
8
|
+
require "oml4r"
|
9
|
+
|
10
|
+
# # Zabbix node names
|
11
|
+
# nodes = ["10.129.16.11", "10.129.16.12", "10.129.16.13"]
|
12
|
+
|
13
|
+
# Define your own Measurement Point
|
14
|
+
class CPU_MP < OML4R::MPBase
|
15
|
+
name :CPU
|
16
|
+
param :ts, :type => :string
|
17
|
+
param :node, :type => :string
|
18
|
+
param :load1, :type => :double
|
19
|
+
param :load5, :type => :double
|
20
|
+
param :load15, :type => :double
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Initialise the OML4R module for your application
|
25
|
+
oml_opts = {
|
26
|
+
:appName => 'zabbix',
|
27
|
+
:domain => 'zabbix-cpu-measurement',
|
28
|
+
:nodeID => 'cloud',
|
29
|
+
:collect => 'file:-'
|
30
|
+
}
|
31
|
+
zabbix_opts = {
|
32
|
+
:url => 'http://cloud.npc.nicta.com.au/zabbix/api_jsonrpc.php',
|
33
|
+
:user => 'Admin',
|
34
|
+
:password => 'zabbix'
|
35
|
+
}
|
36
|
+
|
37
|
+
interval = 1
|
38
|
+
|
39
|
+
nodes = OML4R::init(ARGV, oml_opts) do |op|
|
40
|
+
op.banner = "Usage: #{$0} [options] host1 host2 ...\n"
|
41
|
+
|
42
|
+
op.on( '-i', '--interval SEC', "Query interval in seconds [#{interval}]" ) do |i|
|
43
|
+
interval = i.to_i
|
44
|
+
end
|
45
|
+
op.on( '-s', '--service-url URL', "Zabbix service url [#{zabbix_opts[:url]}]" ) do |u|
|
46
|
+
zabbix_opts[:url] = p
|
47
|
+
end
|
48
|
+
op.on( '-p', '--password PW', "Zabbix password [#{zabbix_opts[:password]}]" ) do |p|
|
49
|
+
zabbix_opts[:password] = p
|
50
|
+
end
|
51
|
+
op.on( '-u', '--user USER', "Zabbix user name [#{zabbix_opts[:user]}]" ) do |u|
|
52
|
+
zabbix_opts[:user] = u
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if nodes.empty?
|
56
|
+
OML4R.logger.error "Missing host list"
|
57
|
+
OML4R::close()
|
58
|
+
exit(-1)
|
59
|
+
end
|
60
|
+
|
61
|
+
# connect to Zabbix JSON API
|
62
|
+
zbx = ZabbixApi.connect(zabbix_opts)
|
63
|
+
|
64
|
+
# catch CTRL-C
|
65
|
+
exit_requested = false
|
66
|
+
Kernel.trap( "INT" ) { exit_requested = true }
|
67
|
+
|
68
|
+
# poll Zabbix API
|
69
|
+
while !exit_requested
|
70
|
+
nodes.each{|n|
|
71
|
+
# https://www.zabbix.com/documentation/2.0/manual/appendix/api/item/get
|
72
|
+
results = zbx.query(
|
73
|
+
:method => "item.get",
|
74
|
+
:params => {
|
75
|
+
:output => "extend",
|
76
|
+
:host => "#{n}",
|
77
|
+
# only interested in CPU load
|
78
|
+
:search => {
|
79
|
+
:name => "Processor load"
|
80
|
+
}
|
81
|
+
}
|
82
|
+
)
|
83
|
+
unless results.empty?
|
84
|
+
l15 = results[0]["lastvalue"]
|
85
|
+
l1 = results[1]["lastvalue"]
|
86
|
+
l5 = results[2]["lastvalue"]
|
87
|
+
#puts "Injecting values #{l1}, #{l5}, #{l15} for node #{n}"
|
88
|
+
# injecting measurements into OML
|
89
|
+
CPU_MP.inject(Time.now.to_s, n, l1, l5, l15)
|
90
|
+
else
|
91
|
+
OML4R.logger.warn "Empty result usually means misspelled host address"
|
92
|
+
end
|
93
|
+
}
|
94
|
+
sleep interval
|
95
|
+
end
|
96
|
+
|
97
|
+
OML4R::close()
|
98
|
+
puts "Exiting"
|
data/bin/test_types
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright (c) 2009 - 2012 National ICT Australia Limited (NICTA).
|
4
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
5
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
6
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
7
|
+
# ------------------
|
8
|
+
#
|
9
|
+
# = test_types.rb
|
10
|
+
#
|
11
|
+
# == Description
|
12
|
+
#
|
13
|
+
# Testing blobs and long strings. Should really go into a test suite.
|
14
|
+
#
|
15
|
+
require 'rubygems'
|
16
|
+
require 'oml4r'
|
17
|
+
|
18
|
+
# Define your own Measurement Points
|
19
|
+
class TestMP < OML4R::MPBase
|
20
|
+
name :test
|
21
|
+
#channel :default
|
22
|
+
|
23
|
+
param :text
|
24
|
+
param :blob, :type => :blob
|
25
|
+
end
|
26
|
+
|
27
|
+
# Initialise the OML4R module for your application
|
28
|
+
opts = {:appName => 'test_types',
|
29
|
+
:domain => 'foo', :nodeID => 'n1',
|
30
|
+
:collect => 'file:-'}
|
31
|
+
|
32
|
+
OML4R::init(ARGV, opts)
|
33
|
+
|
34
|
+
# Now collect and inject some measurements
|
35
|
+
blob = ""
|
36
|
+
30.times {|i| blob << i}
|
37
|
+
TestMP.inject(%{tab new line
|
38
|
+
another two
|
39
|
+
|
40
|
+
and that's it}, blob)
|
41
|
+
|
42
|
+
# Don't forget to close when you are finished
|
43
|
+
OML4R::close()
|
44
|
+
|
45
|
+
# vim: sw=2
|
File without changes
|
File without changes
|
data/examples/oml4r-solar.rb
CHANGED
File without changes
|
data/examples/oml4r-zabbix.rb
CHANGED
File without changes
|
data/examples/test_types.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
# Copyright (c) 2009 - 2012 National ICT Australia Limited (NICTA).
|
2
4
|
# This software may be used and distributed solely under the terms of the MIT license (License).
|
3
5
|
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
data/lib/oml4r/version.rb
CHANGED
data/lib/oml4r.rb
CHANGED
@@ -19,6 +19,7 @@ require 'socket'
|
|
19
19
|
require 'monitor'
|
20
20
|
require 'thread'
|
21
21
|
require 'optparse'
|
22
|
+
require 'securerandom'
|
22
23
|
|
23
24
|
require 'oml4r/version'
|
24
25
|
|
@@ -52,6 +53,7 @@ module OML4R
|
|
52
53
|
class MPBase
|
53
54
|
|
54
55
|
# Some Class variables
|
56
|
+
@@appName = nil
|
55
57
|
@@defs = {}
|
56
58
|
@@channels = {}
|
57
59
|
@@channelNames = {}
|
@@ -112,7 +114,7 @@ module OML4R
|
|
112
114
|
# Set a metric for this MP
|
113
115
|
# - name = name of the metric to set
|
114
116
|
# - opts = a Hash with the options for this metric
|
115
|
-
# Only supported option is :type = { :string | :int32 | :double | :bool }
|
117
|
+
# Only supported option is :type = { :string | :int32 | :double | :bool | :guid }
|
116
118
|
def self.param(name, opts = {})
|
117
119
|
o = opts.dup
|
118
120
|
o[:name] = name
|
@@ -125,49 +127,81 @@ module OML4R
|
|
125
127
|
nil
|
126
128
|
end
|
127
129
|
|
130
|
+
# Inject a metadata measurement from this Measurement Point ot the OML Server.
|
131
|
+
# - key = a string used to identify the key
|
132
|
+
# - value = the string value
|
133
|
+
# - fname = when not nil a string used to qualify the subject name
|
134
|
+
def self.inject_metadata(key, value, fname = nil)
|
135
|
+
|
136
|
+
return unless @@useOML
|
137
|
+
|
138
|
+
# retrieve infos
|
139
|
+
defs = @@defs[self]
|
140
|
+
mp_name_def = defs[:name]
|
141
|
+
mp_name = mp_name_def[:name]
|
142
|
+
pdefs = defs[:p_def]
|
143
|
+
defs[:types] = pdefs.map {|h| h[:type]}
|
144
|
+
|
145
|
+
# construct the subject reference
|
146
|
+
subject = "."
|
147
|
+
if self != OML4R::ExperimentMetadata
|
148
|
+
subject += "#{@@appName}_#{mp_name}"
|
149
|
+
unless fname.nil?
|
150
|
+
subject += ".#{fname}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# prepare the message header
|
155
|
+
a = []
|
156
|
+
a << Time.now - @@start_time
|
157
|
+
a << "0"
|
158
|
+
a << (defs[:meta_no] += 1)
|
159
|
+
a << subject
|
160
|
+
a << key
|
161
|
+
a << value
|
162
|
+
msg = a.join("\t")
|
163
|
+
|
164
|
+
# Setup channels for the ExperimentMetadata MP
|
165
|
+
chans = @@channels[self] || []
|
166
|
+
if chans.empty?
|
167
|
+
@@channels[self] = [[Channel[], 0]]
|
168
|
+
end
|
169
|
+
|
170
|
+
# now inject the schema
|
171
|
+
@@channels[self].each do |ca|
|
172
|
+
channel = ca[0]
|
173
|
+
index = ca[1]
|
174
|
+
channel.send msg
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
128
178
|
# Inject a measurement from this Measurement Point to the OML Server
|
129
179
|
# However, if useOML flag is false, then only prints the measurement on stdout
|
130
180
|
# - args = a list of arguments (comma separated) which correspond to the
|
131
181
|
# different values of the metrics for the measurement to inject
|
132
182
|
def self.inject(*args)
|
133
|
-
|
134
183
|
return unless @@useOML
|
135
184
|
|
136
|
-
|
185
|
+
defs = __def__()
|
186
|
+
|
187
|
+
# Do we need to send the schema?
|
137
188
|
if @@newDefs.include? self
|
138
|
-
|
189
|
+
# Identify MP details
|
139
190
|
mp_name_def = defs[:name]
|
140
191
|
mp_name = mp_name_def[:name]
|
141
192
|
pdefs = defs[:p_def]
|
142
193
|
defs[:types] = pdefs.map {|h| h[:type]}
|
143
|
-
#
|
144
|
-
|
145
|
-
a << Time.now - @@start_time
|
146
|
-
a << "0"
|
147
|
-
a << (defs[:meta_no] += 1)
|
148
|
-
a << "."
|
149
|
-
a << "schema"
|
150
|
-
msg = a.join("\t")
|
151
|
-
# Create the channels
|
152
|
-
names = @@channelNames[self] || []
|
153
|
-
chans = names.collect do |cname, domain|
|
154
|
-
[Channel[cname.to_sym, domain.to_sym]]
|
155
|
-
end
|
156
|
-
@@channels[self] = chans.empty? ? [[Channel[]]] : chans
|
157
|
-
# Now inject the schema
|
158
|
-
meta_ca = @@channels[OML4R::ExperimentMetadata][0]
|
159
|
-
channel = meta_ca[0]
|
194
|
+
# Setup channel and schema
|
195
|
+
channel = Channel[]
|
160
196
|
schema_info = channel.build_schema(mp_name, mp_name_def[:opts][:add_prefix], pdefs)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
end
|
197
|
+
@@channels[self] = [[channel, schema_info[0]]]
|
198
|
+
# Inject it!
|
199
|
+
ExperimentMetadata.inject_metadata("schema", schema_info[1])
|
165
200
|
@@newDefs.delete self
|
166
201
|
end
|
167
202
|
|
168
203
|
# Check that the list of values passed as argument matches the
|
169
204
|
# definition of this Measurement Point
|
170
|
-
defs = __def__()
|
171
205
|
pdef = defs[:p_def]
|
172
206
|
types = defs[:types]
|
173
207
|
if args.size != pdef.size
|
@@ -200,6 +234,7 @@ module OML4R
|
|
200
234
|
index = ca[1]
|
201
235
|
channel.send "#{t}\t#{index}\t#{msg}"
|
202
236
|
end
|
237
|
+
|
203
238
|
args
|
204
239
|
end
|
205
240
|
|
@@ -233,7 +268,7 @@ module OML4R
|
|
233
268
|
[Channel[cname.to_sym, domain.to_sym]]
|
234
269
|
end
|
235
270
|
OML4R.logger.debug "Using channels '#{chans.inspect}"
|
236
|
-
@@channels[klass] = chans.empty? ? [[Channel[]]] : chans
|
271
|
+
@@channels[klass] = chans.empty? ? [[Channel[], 0]] : chans
|
237
272
|
end
|
238
273
|
@@start_time = start_time
|
239
274
|
end
|
@@ -287,7 +322,7 @@ module OML4R
|
|
287
322
|
# param block = a block which defines the additional application-specific arguments
|
288
323
|
#
|
289
324
|
def self.init(argv, opts = {}, &block)
|
290
|
-
OML4R.logger.info "
|
325
|
+
OML4R.logger.info "OML4R Client #{VERSION} [OMSPv#{opts[:protocol] || DEF_PROTOCOL}; Ruby #{RUBY_VERSION}] #{COPYRIGHT}"
|
291
326
|
if d = (ENV['OML_EXP_ID'] || opts[:expID])
|
292
327
|
# NOTE: It is still too early to complain about that. We need to be sure
|
293
328
|
# of the nomenclature before making user-visible changes.
|
@@ -308,6 +343,7 @@ module OML4R
|
|
308
343
|
# raise 'OML4R: :app is not a valid option. Do you mean :appName?'
|
309
344
|
#end
|
310
345
|
opts[:appName] ||= opts[:app]
|
346
|
+
@@appName = opts[:appName]
|
311
347
|
opts[:protocol] ||= DEF_PROTOCOL
|
312
348
|
|
313
349
|
if ENV['OML_URL'] || opts[:omlURL] || opts[:url]
|
@@ -330,7 +366,7 @@ module OML4R
|
|
330
366
|
op.on("--oml-domain domain", "Name of experimental domain [#{opts[:domain] || 'undefined'}] *EXPERIMENTAL*") { |name| opts[:domain] = name }
|
331
367
|
op.on("--oml-collect uri", "URI of server to send measurements to") { |u| opts[:omlCollectUri] = u }
|
332
368
|
op.on("--oml-protocol p", "Protocol number [#{OML4R::DEF_PROTOCOL}]") { |l| opts[:protocol] = l.to_i }
|
333
|
-
op.on("--oml-log-level l", "Log level used (info:
|
369
|
+
op.on("--oml-log-level l", "Log level used (info: 0 .. debug: 1)") { |l| OML4R.logger.level = 1 - l.to_i }
|
334
370
|
op.on("--oml-noop", "Do not collect measurements") { noop = true }
|
335
371
|
op.on("--oml-config file", "File holding OML configuration parameters") { |f| omlConfigFile = f }
|
336
372
|
op.on("--oml-exp-id domain", "Obsolescent equivalent to --oml-domain domain") { |name|
|
@@ -350,12 +386,12 @@ module OML4R
|
|
350
386
|
#op.on("--oml-appid APPID", "Application ID for OML [#{appName || 'undefined'}] *EXPERIMENTAL*") { |name| appID = name }
|
351
387
|
|
352
388
|
# Now parse the command line
|
353
|
-
OML4R.logger.debug "ARGV: #{argv.inspect}"
|
354
389
|
rest = op.parse(argv)
|
355
390
|
if opts[:afterParse]
|
356
391
|
# give the app a chance to fix missing parameters
|
357
392
|
opts[:afterParse].call(opts)
|
358
393
|
end
|
394
|
+
OML4R.logger.debug "ARGV: #{argv.inspect}"
|
359
395
|
return if noop
|
360
396
|
# Parameters in OML config file takes precedence
|
361
397
|
unless omlConfigFile.nil?
|
@@ -471,6 +507,13 @@ module OML4R
|
|
471
507
|
Channel.close_all
|
472
508
|
end
|
473
509
|
|
510
|
+
# Generate a random GUID
|
511
|
+
#
|
512
|
+
# @return [BigNum] An integer GUID.
|
513
|
+
def self.generate_guid()
|
514
|
+
SecureRandom.random_number(2**64)
|
515
|
+
end
|
516
|
+
|
474
517
|
|
475
518
|
#
|
476
519
|
# Measurement Channel
|
@@ -722,7 +765,7 @@ module OML4R
|
|
722
765
|
|
723
766
|
class Logger < ::Logger
|
724
767
|
def format_message(severity, time, progname, message)
|
725
|
-
"%
|
768
|
+
"%s\t%s\n" % [severity, message]
|
726
769
|
end
|
727
770
|
end
|
728
771
|
|
data/oml4r.gemspec
CHANGED
metadata
CHANGED
@@ -1,20 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oml4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.10.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- NICTA
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-12-09 00:00:00.000000000 Z
|
12
13
|
dependencies: []
|
13
14
|
description: ! '["Simple OML client library and applications for Ruby"]'
|
14
15
|
email:
|
15
16
|
- oml-user@lists.nicta.com.au
|
16
17
|
executables:
|
18
|
+
- oml4r-multiple-channel-example
|
19
|
+
- oml4r-neuca-beacon
|
20
|
+
- oml4r-orca-beacon
|
21
|
+
- oml4r-simple-example
|
22
|
+
- oml4r-solar
|
23
|
+
- oml4r-wlanconfig
|
24
|
+
- oml4r-zabbix
|
17
25
|
- ping-oml2
|
26
|
+
- test_types
|
18
27
|
extensions: []
|
19
28
|
extra_rdoc_files: []
|
20
29
|
files:
|
@@ -23,7 +32,15 @@ files:
|
|
23
32
|
- LICENSE.txt
|
24
33
|
- README.md
|
25
34
|
- Rakefile
|
35
|
+
- bin/oml4r-multiple-channel-example
|
36
|
+
- bin/oml4r-neuca-beacon
|
37
|
+
- bin/oml4r-orca-beacon
|
38
|
+
- bin/oml4r-simple-example
|
39
|
+
- bin/oml4r-solar
|
40
|
+
- bin/oml4r-wlanconfig
|
41
|
+
- bin/oml4r-zabbix
|
26
42
|
- bin/ping-oml2
|
43
|
+
- bin/test_types
|
27
44
|
- examples/oml4r-multiple-channel-example.rb
|
28
45
|
- examples/oml4r-neuca-beacon.rb
|
29
46
|
- examples/oml4r-orca-beacon.rb
|
@@ -42,29 +59,29 @@ files:
|
|
42
59
|
homepage: http://oml.mytestbed.net
|
43
60
|
licenses:
|
44
61
|
- MIT
|
45
|
-
metadata: {}
|
46
62
|
post_install_message:
|
47
63
|
rdoc_options: []
|
48
64
|
require_paths:
|
49
65
|
- lib
|
50
66
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
51
68
|
requirements:
|
52
|
-
- -
|
69
|
+
- - ~>
|
53
70
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
71
|
+
version: '1.9'
|
55
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
56
74
|
requirements:
|
57
75
|
- - ! '>='
|
58
76
|
- !ruby/object:Gem::Version
|
59
77
|
version: '0'
|
60
78
|
requirements: []
|
61
79
|
rubyforge_project:
|
62
|
-
rubygems_version:
|
80
|
+
rubygems_version: 1.8.23
|
63
81
|
signing_key:
|
64
|
-
specification_version:
|
82
|
+
specification_version: 3
|
65
83
|
summary: ! '["This is a simple client library for OML which does not use liboml2 and
|
66
84
|
its filters, but connects directly to the server using the +text+ protocol. User
|
67
85
|
can use this library to create ruby applications which can send measurement to the
|
68
86
|
OML collection server. The gem ships with some example applications."]'
|
69
87
|
test_files: []
|
70
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
NzExMmRjZTY5YjU4ZDFmNjg2NzU2NDMzNWFmNThhZTAyOWY3ZDNhZg==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NGU4MmY5MjQ5M2UyMzViNjA5ODMwY2Q3MmY3ZjIzY2VmYmM0YWQ1YQ==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
NzI0ZjFhMWU1MTI3NGU5YmU5OGYwMzAyZDliZmYwMzBhZmI3MzM1OWVkNjQ2
|
10
|
-
ZTNjNDQ0Y2FlOWEwYjA0MGJkOTc0OGJmNjA0YzY4ZTMxODk4MGJhNmQ3YTJi
|
11
|
-
Y2E0MjAxOTJjMDc2OTQwMDQyYjVkNTFiMzAyMTAxZTkyZjA4Y2M=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MDE0ODUxZGU3OGZjNTcyZDFlYTFkNzkwZDhkZjM5ZTkxMjE4NjBkMmFmN2Mw
|
14
|
-
MWViYWQ2Yzg2MWE4YTc5MWVjNWRmMDMwOTRlYzMzZjk2NzgwNjYzYTM1ZjBh
|
15
|
-
M2IwMDRkOWVmOTkyZWYyYzRiNzY2YTZhZjgyOGMzNWIyYWM1MmE=
|