oml4r 2.9.10 → 2.10.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/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=
|