oml4r 2.9.1 → 2.9.3
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/README.md +6 -1
- data/examples/oml4r-multiple-channel-example.rb +79 -0
- data/examples/oml4r-neuca-beacon.rb +52 -0
- data/examples/oml4r-orca-beacon.rb +56 -0
- data/examples/oml4r-solar.rb +74 -0
- data/examples/oml4r-wlanconfig.rb +1 -1
- data/lib/oml4r/log4r/oml_outputter.rb +105 -0
- data/lib/oml4r/version.rb +1 -1
- data/lib/oml4r.rb +109 -82
- metadata +8 -3
data/README.md
CHANGED
@@ -6,7 +6,7 @@ filters, but connects directly to the server using the text protocol [oml-text].
|
|
6
6
|
User can use this library to create ruby applications which can send
|
7
7
|
measurement to the OML collection server. A simple example on how to use
|
8
8
|
this library is attached at the end of this file. Another example can be
|
9
|
-
found in the file oml4r-example.rb
|
9
|
+
found in the file oml4r-example.rb .
|
10
10
|
|
11
11
|
Installation
|
12
12
|
------------
|
@@ -78,3 +78,8 @@ See examples files oml4r-simple-example.rb and oml4r-wlanconfig.rb.
|
|
78
78
|
|
79
79
|
[oml-text]: http://oml.mytestbed.net/projects/oml/wiki/Description_of_Text_protocol
|
80
80
|
[oml4r-rubygem]: https://rubygems.org/gems/oml4r/
|
81
|
+
|
82
|
+
License
|
83
|
+
-------
|
84
|
+
|
85
|
+
Please see LICENSE.txt
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (c) 2013 National ICT Australia Limited (NICTA).
|
2
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
3
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
4
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
5
|
+
# ------------------
|
6
|
+
#
|
7
|
+
# = oml4r-multiple-channel-example.rb
|
8
|
+
#
|
9
|
+
# == Description
|
10
|
+
#
|
11
|
+
# An extension of the 'oml4r-simple.example.rb' example demonstrating the use of
|
12
|
+
# multiple destinations for different measurements.
|
13
|
+
#
|
14
|
+
# == Usage
|
15
|
+
#
|
16
|
+
# The following write the COS measurements to STDOUT (file:-) and the SIN
|
17
|
+
# measurements to /tmp/ch2.oml (which can be overwrriten with the --oml-ch2 option)
|
18
|
+
#
|
19
|
+
# % cd $OML_HOME
|
20
|
+
# % ruby -I lib examples/oml4r-multiple-channel-example.rb --oml-ch1 file:-
|
21
|
+
#
|
22
|
+
# Use --oml-help to get all available options
|
23
|
+
#
|
24
|
+
# % cd $OML_HOME
|
25
|
+
# % ruby -I lib examples/oml4r-multiple-channel-example.rb --oml-help
|
26
|
+
#
|
27
|
+
require 'rubygems'
|
28
|
+
require 'oml4r'
|
29
|
+
|
30
|
+
# Define your own Measurement Points
|
31
|
+
class SinMP < OML4R::MPBase
|
32
|
+
name :sin
|
33
|
+
channel :ch1
|
34
|
+
|
35
|
+
param :label
|
36
|
+
param :angle, :type => :int32
|
37
|
+
param :value, :type => :double
|
38
|
+
end
|
39
|
+
|
40
|
+
class CosMP < OML4R::MPBase
|
41
|
+
name :cos
|
42
|
+
channel :ch2
|
43
|
+
|
44
|
+
param :label
|
45
|
+
param :value, :type => :double
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initialise the OML4R module for your application
|
49
|
+
opts = {
|
50
|
+
:appName => 'oml4rSimpleExample',
|
51
|
+
:domain => 'foo',
|
52
|
+
:create_default_channel => false # we don't need the default channel
|
53
|
+
}
|
54
|
+
#
|
55
|
+
ch1 = OML4R::create_channel(:ch1, 'file:/tmp/ch1.oml')
|
56
|
+
ch2 = OML4R::create_channel(:ch2, 'file:/tmp/ch2.oml')
|
57
|
+
|
58
|
+
begin
|
59
|
+
OML4R::init(ARGV, opts) do |op|
|
60
|
+
op.on("--oml-ch1 URL", "Set destination for Channel 1 [#{ch1.url}]") { |url| ch1.url = url }
|
61
|
+
op.on("--oml-ch2 URL", "Set destination for Channel 2 [#{ch2.url}]") { |url| ch2.url = url }
|
62
|
+
end
|
63
|
+
rescue OML4R::MissingArgumentException => mex
|
64
|
+
$stderr.puts mex
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
68
|
+
# Now collect and inject some measurements
|
69
|
+
500.times do |i|
|
70
|
+
sleep 0.5
|
71
|
+
angle = 15 * i
|
72
|
+
SinMP.inject("label_#{angle}", angle, Math.sin(angle))
|
73
|
+
CosMP.inject("label_#{angle}", Math.cos(angle))
|
74
|
+
end
|
75
|
+
|
76
|
+
# Don't forget to close when you are finished
|
77
|
+
OML4R::close()
|
78
|
+
|
79
|
+
# 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,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()
|
@@ -75,7 +75,7 @@ class Wrapper
|
|
75
75
|
|
76
76
|
# Now call the Init of OML4R with the command line arguments (args)
|
77
77
|
# and a block defining the arguments specific to this wrapper
|
78
|
-
OML4R::init(args, :appName => "#{APPNAME}_wrapper") { |argParser|
|
78
|
+
OML4R::init(args, :appName => "#{APPNAME}_wrapper", :domain => 'foo', :collect => 'file:-') { |argParser|
|
79
79
|
argParser.banner = "\nExecute a wrapper around #{APPNAME}\n" +
|
80
80
|
"Use -h or --help for a list of options\n\n"
|
81
81
|
argParser.on("-i", "--interface IFNAME", "Name of Interface to monitor") { |name| @interface = name }
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Copyright (c) 2013 National ICT Australia Limited (NICTA).
|
2
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
3
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
4
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
5
|
+
# ------------------
|
6
|
+
|
7
|
+
require 'log4r/outputter/outputter'
|
8
|
+
require 'oml4r'
|
9
|
+
require 'time'
|
10
|
+
|
11
|
+
module Log4r
|
12
|
+
|
13
|
+
# Log4r outputter which turn logging events into an OML stream
|
14
|
+
#
|
15
|
+
class OmlOutputter < Log4r::Outputter
|
16
|
+
|
17
|
+
class LogEventMP < OML4R::MPBase
|
18
|
+
name :log #, add_prefix: false
|
19
|
+
|
20
|
+
param :level, :type => :int32
|
21
|
+
param :name
|
22
|
+
param :tracer
|
23
|
+
param :data
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# Initialise an outputter which turns logging messages
|
28
|
+
# into an OML stream
|
29
|
+
#
|
30
|
+
# param name Name of outputter
|
31
|
+
# param opts Options for setting up OML
|
32
|
+
# opts collect If set to an URL, then initialise OML otherwise assume that someone else is doing it
|
33
|
+
# opts domain OML domain to send to (assumes that 'collect' is set) ['log']
|
34
|
+
# opts appName OML domain to send to (assumes that 'collect' is set) [fileName-time-pid]
|
35
|
+
#
|
36
|
+
def initialize(name, opts = {})
|
37
|
+
super(name, opts)
|
38
|
+
if url = opts['collect']
|
39
|
+
h = {}
|
40
|
+
opts.each {|k, v| h[k.to_sym] = v}
|
41
|
+
opts = h
|
42
|
+
|
43
|
+
opts[:domain] ||= 'log'
|
44
|
+
opts[:appName] ||= File.basename(__FILE__, '.*')
|
45
|
+
opts[:id] ||= "#{Socket.gethostname}-#{Time.now.iso8601}-#{Process.pid}"
|
46
|
+
OML4R.init(nil, opts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def closed?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def close
|
55
|
+
# OutputterFactory.create_methods(self)
|
56
|
+
# Logger.log_internal {"Outputter '#{@name}' closed Syslog and set to OFF"}
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def canonical_log(le)
|
62
|
+
LogEventMP.inject le.level, le.fullname, le.tracer || '', le.data || ''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
if __FILE__ == $0
|
69
|
+
require 'log4r'
|
70
|
+
require 'log4r/configurator'
|
71
|
+
require 'log4r/yamlconfigurator'
|
72
|
+
require 'yaml'
|
73
|
+
|
74
|
+
yf = %{
|
75
|
+
log4r:
|
76
|
+
|
77
|
+
# define all loggers ...
|
78
|
+
loggers:
|
79
|
+
- name : production
|
80
|
+
level : DEBUG
|
81
|
+
trace : 'false'
|
82
|
+
outputters:
|
83
|
+
- oml
|
84
|
+
outputters:
|
85
|
+
- name : oml
|
86
|
+
type : OmlOutputter
|
87
|
+
collect : file:-
|
88
|
+
}
|
89
|
+
|
90
|
+
ycfg = YAML.load yf
|
91
|
+
#puts ycfg['log4r'].inspect
|
92
|
+
::Log4r::YamlConfigurator.decode_yaml(ycfg['log4r'])
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
log = ::Log4r::Logger['production']
|
97
|
+
log.info 'test'
|
98
|
+
log.debug 'test2'
|
99
|
+
|
100
|
+
log2 = Log4r::Logger.new 'production::foo'
|
101
|
+
log2.debug 'debugging!'
|
102
|
+
|
103
|
+
sleep 2
|
104
|
+
|
105
|
+
end
|
data/lib/oml4r/version.rb
CHANGED
data/lib/oml4r.rb
CHANGED
@@ -36,7 +36,7 @@ module OML4R
|
|
36
36
|
def self.logger=(logger)
|
37
37
|
@@logger = logger
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
class OML4RExeption < Exception; end
|
41
41
|
class MissingArgumentException < OML4RExeption; end
|
42
42
|
class ArgumentMismatchException < OML4RExeption; end
|
@@ -76,8 +76,15 @@ module OML4R
|
|
76
76
|
end
|
77
77
|
|
78
78
|
# Set a name for this MP
|
79
|
-
|
80
|
-
|
79
|
+
#
|
80
|
+
# param opts Options
|
81
|
+
# opts add_prefix Add app name as prefix to table. Default: true
|
82
|
+
#
|
83
|
+
def self.name(name, opts = {})
|
84
|
+
if opts[:add_prefix].nil?
|
85
|
+
opts[:add_prefix] = true
|
86
|
+
end
|
87
|
+
__def__()[:name] = {name: name, opts: opts}
|
81
88
|
end
|
82
89
|
|
83
90
|
# Set the channel these measurements should be sent out on.
|
@@ -96,7 +103,7 @@ module OML4R
|
|
96
103
|
o = opts.dup
|
97
104
|
o[:name] = name
|
98
105
|
o[:type] ||= :string
|
99
|
-
case o[:type]
|
106
|
+
case o[:type]
|
100
107
|
when :long
|
101
108
|
OML4R.logger.warn ":long is deprecated use, :int32 instead"
|
102
109
|
o[:type] = :int32
|
@@ -194,10 +201,11 @@ module OML4R
|
|
194
201
|
defs = __def__()
|
195
202
|
|
196
203
|
# Do some sanity checks...
|
197
|
-
unless (
|
204
|
+
unless (mp_name_def = defs[:name])
|
198
205
|
raise MissingArgumentException.new "Missing 'name' declaration for '#{self}'"
|
199
206
|
end
|
200
|
-
|
207
|
+
mp_name = mp_name_def[:name]
|
208
|
+
if !name_prefix.nil? && mp_name_def[:opts][:add_prefix]
|
201
209
|
mp_name = "#{name_prefix}_#{mp_name}"
|
202
210
|
end
|
203
211
|
|
@@ -227,14 +235,14 @@ module OML4R
|
|
227
235
|
OML4R#{VERSION_STRING} [#{COPYRIGHT}")
|
228
236
|
|
229
237
|
if d = (ENV['OML_EXP_ID'] || opts[:expID])
|
230
|
-
#
|
238
|
+
# NOTE: It is still too early to complain about that. We need to be sure
|
231
239
|
# of the nomenclature before making user-visible changes.
|
232
240
|
OML4R.logger.warn "opts[:expID] and ENV['OML_EXP_ID'] are getting deprecated; please use opts[:domain] or ENV['OML_DOMAIN'] instead"
|
233
241
|
opts[:domain] ||= d
|
234
242
|
end
|
235
243
|
domain ||= ENV['OML_DOMAIN'] || opts[:domain]
|
236
244
|
|
237
|
-
#
|
245
|
+
# TODO: Same as above; here, though, :id might actually be the way to go; or
|
238
246
|
# perhaps instId?
|
239
247
|
#if opts[:id]
|
240
248
|
# raise 'OML4R: :id is not a valid option. Do you mean :nodeID?'
|
@@ -257,75 +265,80 @@ module OML4R
|
|
257
265
|
omlCollectUri = ENV['OML_COLLECT'] || ENV['OML_SERVER'] || opts[:collect] || opts[:omlServer]
|
258
266
|
noop = opts[:noop] || false
|
259
267
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
268
|
+
if argv
|
269
|
+
# Create a new Parser for the command line
|
270
|
+
op = OptionParser.new
|
271
|
+
# Include the definition of application's specific arguments
|
272
|
+
yield(op) if block
|
273
|
+
# Include the definition of OML specific arguments
|
274
|
+
op.on("--oml-id id", "Name to identify this app instance [#{nodeID || 'undefined'}]") { |name| nodeID = name }
|
275
|
+
op.on("--oml-domain domain", "Name of experimental domain [#{domain || 'undefined'}] *EXPERIMENTAL*") { |name| domain = name }
|
276
|
+
op.on("--oml-collect uri", "URI of server to send measurements to") { |u| omlCollectUri = u }
|
277
|
+
op.on("--oml-protocol p", "Protocol number [#{OML4R::DEF_PROTOCOL}]") { |l| protocol = l.to_i }
|
278
|
+
op.on("--oml-log-level l", "Log level used (info: 1 .. debug: 0)") { |l| OML4R.logger.level = l.to_i }
|
279
|
+
op.on("--oml-noop", "Do not collect measurements") { noop = true }
|
280
|
+
op.on("--oml-exp-id domain", "Obsolescent equivalent to --oml-domain domain") { |name|
|
281
|
+
domain = name
|
282
|
+
OML4R.logger.warn "Option --oml-exp-id is getting deprecated; please use '--oml-domain #{domain}' instead"
|
283
|
+
}
|
284
|
+
op.on("--oml-file localPath", "Obsolescent equivalent to --oml-collect file:localPath") { |name|
|
285
|
+
omlCollectUri = "file:#{name}"
|
286
|
+
OML4R.logger.warn "Option --oml-file is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
|
287
|
+
}
|
288
|
+
op.on("--oml-server uri", "Obsolescent equivalent to --oml-collect uri") {|u|
|
289
|
+
omlCollectUri = u
|
290
|
+
OML4R.logger.warn "Option --oml-server is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
|
291
|
+
}
|
292
|
+
op.on_tail("--oml-help", "Show this message") { $stderr.puts op; exit }
|
293
|
+
# XXX: This should be set by the application writer, not the command line
|
294
|
+
#op.on("--oml-appid APPID", "Application ID for OML [#{appName || 'undefined'}] *EXPERIMENTAL*") { |name| appID = name }
|
295
|
+
|
296
|
+
# Now parse the command line
|
297
|
+
OML4R.logger.debug "ARGV: #{argv.inspect}"
|
298
|
+
rest = op.parse(argv)
|
299
|
+
return if noop
|
300
|
+
end
|
292
301
|
|
293
302
|
unless nodeID
|
294
303
|
begin
|
295
304
|
# Create a default nodeID by concatinating the local hostname with the process ID
|
296
305
|
hostname = nil
|
297
|
-
begin
|
306
|
+
begin
|
298
307
|
hostname = Socket.gethostbyname(Socket.gethostname)[0]
|
299
|
-
rescue Exception
|
308
|
+
rescue Exception
|
300
309
|
begin
|
301
310
|
hostname = `hostname`
|
302
|
-
rescue Exception; end
|
311
|
+
rescue Exception; end
|
303
312
|
end
|
304
313
|
if hostname
|
305
314
|
nodeID = "#{hostname}-#{Process.pid}"
|
306
315
|
end
|
307
316
|
end
|
308
317
|
unless nodeID
|
309
|
-
raise MissingArgumentException.new 'OML4R: Missing values for parameter :nodeID (--oml-id)'
|
318
|
+
raise MissingArgumentException.new 'OML4R: Missing values for parameter :nodeID (--oml-id)'
|
310
319
|
end
|
311
320
|
end
|
312
|
-
|
321
|
+
|
313
322
|
unless domain && appName
|
314
323
|
raise MissingArgumentException.new 'OML4R: Missing values for parameters :domain (--oml-domain), :nodeID (--oml-id), or :appName (in code)!'
|
315
324
|
end
|
316
325
|
|
317
|
-
# Set a default collection URI if nothing has been specified
|
318
|
-
omlCollectUri ||= "file:#{appName}_#{nodeID}_#{domain}_#{Time.now.strftime("%Y-%m-%dt%H.%M.%S%z")}"
|
319
326
|
|
320
|
-
|
327
|
+
unless opts[:create_default_channel] == false
|
328
|
+
# Set a default collection URI if nothing has been specified
|
329
|
+
unless omlCollectUri
|
330
|
+
omlCollectUri = "file:#{appName}_#{nodeID}_#{domain}_#{Time.now.strftime("%Y-%m-%dt%H.%M.%S%z")}"
|
331
|
+
OML4R.logger.info "Collection URI is #{omlCollectUri}"
|
332
|
+
end
|
333
|
+
create_channel(:default, omlCollectUri)
|
334
|
+
end
|
321
335
|
|
322
336
|
# Handle the defined Measurement Points
|
323
337
|
startTime = Time.now
|
324
338
|
Channel.init_all(domain, nodeID, appName, startTime, protocol)
|
325
|
-
OML4R.logger.info "Collection URI is #{omlCollectUri}"
|
326
339
|
rest || []
|
327
340
|
end
|
328
|
-
|
341
|
+
|
329
342
|
def self.create_channel(name, url)
|
330
343
|
Channel.create(name, url)
|
331
344
|
end
|
@@ -348,8 +361,8 @@ module OML4R
|
|
348
361
|
class Channel
|
349
362
|
@@channels = {}
|
350
363
|
@@default_domain = nil
|
351
|
-
|
352
|
-
|
364
|
+
|
365
|
+
|
353
366
|
|
354
367
|
def self.create(name, url, domain = :default)
|
355
368
|
key = "#{name}:#{domain}"
|
@@ -359,28 +372,15 @@ module OML4R
|
|
359
372
|
end
|
360
373
|
return channel
|
361
374
|
end
|
362
|
-
return self._create(key, domain, url)
|
375
|
+
#return self._create(key, domain, url)
|
376
|
+
return @@channels[key] = self.new(url, domain)
|
363
377
|
end
|
364
378
|
|
365
|
-
def self._create(key, domain, url)
|
366
|
-
out = _connect(url)
|
367
|
-
@@channels[key] = self.new(url, domain, out)
|
368
|
-
end
|
379
|
+
# def self._create(key, domain, url)
|
380
|
+
# out = _connect(url)
|
381
|
+
# @@channels[key] = self.new(url, domain, out)
|
382
|
+
# end
|
369
383
|
|
370
|
-
def self._connect(url)
|
371
|
-
if url.start_with? 'file:'
|
372
|
-
proto, fname = url.split(':')
|
373
|
-
out = (fname == '-' ? $stdout : File.open(fname, "w+"))
|
374
|
-
elsif url.start_with? 'tcp:'
|
375
|
-
#tcp:norbit.npc.nicta.com.au:3003
|
376
|
-
proto, host, port = url.split(':')
|
377
|
-
port ||= DEF_SERVER_PORT
|
378
|
-
out = TCPSocket.new(host, port)
|
379
|
-
else
|
380
|
-
raise OML4RException.new "OML4R: Unknown transport in server url '#{url}'"
|
381
|
-
end
|
382
|
-
out
|
383
|
-
end
|
384
384
|
|
385
385
|
def self.[](name = :default, domain = :default)
|
386
386
|
key = "#{name}:#{domain}"
|
@@ -398,6 +398,10 @@ module OML4R
|
|
398
398
|
|
399
399
|
def self.init_all(domain, nodeID, appName, startTime, protocol)
|
400
400
|
@@default_domain = domain
|
401
|
+
@@nodeID = nodeID
|
402
|
+
@@appName = appName
|
403
|
+
@@startTime = startTime
|
404
|
+
@@protocol = protocol
|
401
405
|
|
402
406
|
MPBase.__freeze__(appName, startTime)
|
403
407
|
|
@@ -420,6 +424,14 @@ module OML4R
|
|
420
424
|
|
421
425
|
attr_reader :url
|
422
426
|
|
427
|
+
def url=(url)
|
428
|
+
return if @url == url
|
429
|
+
if @out
|
430
|
+
raise "Can't change channel's URL when it is already connected"
|
431
|
+
end
|
432
|
+
@url = url
|
433
|
+
end
|
434
|
+
|
423
435
|
def send_schema(mp_name, pdefs) # defs[:p_def]
|
424
436
|
# Build the schema and send it
|
425
437
|
@index += 1
|
@@ -439,6 +451,7 @@ module OML4R
|
|
439
451
|
|
440
452
|
def init(nodeID, appName, startTime, protocol)
|
441
453
|
@nodeID, @appName, @startTime, @protocol = nodeID, appName, startTime, protocol
|
454
|
+
@out = _connect(@url)
|
442
455
|
end
|
443
456
|
|
444
457
|
def close()
|
@@ -447,10 +460,9 @@ module OML4R
|
|
447
460
|
end
|
448
461
|
|
449
462
|
protected
|
450
|
-
def initialize(url, domain
|
463
|
+
def initialize(url, domain)
|
451
464
|
@domain = domain
|
452
465
|
@url = url
|
453
|
-
@out = out_channel
|
454
466
|
@index = 0
|
455
467
|
@schemas = []
|
456
468
|
@header_sent = false
|
@@ -458,6 +470,21 @@ module OML4R
|
|
458
470
|
start_runner
|
459
471
|
end
|
460
472
|
|
473
|
+
def _connect(url)
|
474
|
+
if url.start_with? 'file:'
|
475
|
+
proto, fname = url.split(':')
|
476
|
+
out = (fname == '-' ? $stdout : File.open(fname, "w+"))
|
477
|
+
elsif url.start_with? 'tcp:'
|
478
|
+
#tcp:norbit.npc.nicta.com.au:3003
|
479
|
+
proto, host, port = url.split(':')
|
480
|
+
port ||= DEF_SERVER_PORT
|
481
|
+
out = TCPSocket.new(host, port)
|
482
|
+
else
|
483
|
+
raise OML4RException.new "OML4R: Unknown transport in server url '#{url}'"
|
484
|
+
end
|
485
|
+
@out = out
|
486
|
+
end
|
487
|
+
|
461
488
|
|
462
489
|
def _send_protocol_header(stream)
|
463
490
|
header = []
|
@@ -474,10 +501,10 @@ module OML4R
|
|
474
501
|
@schemas.each do |s|
|
475
502
|
header << "schema: #{s}"
|
476
503
|
end
|
477
|
-
header << ""
|
504
|
+
header << ""
|
478
505
|
when 4
|
479
506
|
i = 0
|
480
|
-
header << ""
|
507
|
+
header << ""
|
481
508
|
header << "0\t0\t#{i += 1}\t.\texperiment-id\t#{d}"
|
482
509
|
header << "0\t0\t#{i += 1}\t.\tstart_time\t#{@startTime.tv_sec}"
|
483
510
|
header << "0\t0\t#{i += 1}\t.\tsender-id\t#{@nodeID}"
|
@@ -485,7 +512,7 @@ module OML4R
|
|
485
512
|
@schemas.each do |s|
|
486
513
|
header << "0\t0\t#{i += 1}\t.\tschema\t#{s}"
|
487
514
|
end
|
488
|
-
|
515
|
+
|
489
516
|
else
|
490
517
|
raise OML4RException.new "Unsupported protocol #{@protocol}"
|
491
518
|
end
|
@@ -552,23 +579,23 @@ module OML4R
|
|
552
579
|
end
|
553
580
|
|
554
581
|
end # Channel
|
555
|
-
|
582
|
+
|
556
583
|
require 'logger'
|
557
|
-
|
584
|
+
|
558
585
|
class Logger < ::Logger
|
559
586
|
def format_message(severity, time, progname, message)
|
560
587
|
"%5s oml4r: %s\n" % [severity, message]
|
561
588
|
end
|
562
589
|
end
|
563
|
-
|
590
|
+
|
564
591
|
@@logger = Logger.new(STDERR)
|
565
592
|
@@logger.level = ::Logger::INFO
|
566
|
-
|
593
|
+
|
567
594
|
def self.logger
|
568
595
|
@@logger
|
569
596
|
end
|
570
|
-
|
571
|
-
|
597
|
+
|
598
|
+
|
572
599
|
end # module OML4R
|
573
600
|
|
574
601
|
# vim: sw=2
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oml4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.9.
|
4
|
+
version: 2.9.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! '["Simple OML client library for Ruby"]'
|
15
15
|
email:
|
@@ -23,12 +23,17 @@ files:
|
|
23
23
|
- LICENSE.txt
|
24
24
|
- README.md
|
25
25
|
- Rakefile
|
26
|
+
- examples/oml4r-multiple-channel-example.rb
|
27
|
+
- examples/oml4r-neuca-beacon.rb
|
28
|
+
- examples/oml4r-orca-beacon.rb
|
26
29
|
- examples/oml4r-simple-example.rb
|
30
|
+
- examples/oml4r-solar.rb
|
27
31
|
- examples/oml4r-wlanconfig.rb
|
28
32
|
- examples/oml4r-zabbix.rb
|
29
33
|
- examples/test_types.rb
|
30
34
|
- lib/oml4r.rb
|
31
35
|
- lib/oml4r/benchmark.rb
|
36
|
+
- lib/oml4r/log4r/oml_outputter.rb
|
32
37
|
- lib/oml4r/version.rb
|
33
38
|
- oml4r.gemspec
|
34
39
|
homepage: http://oml.mytestbed.net
|
@@ -52,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
57
|
version: '0'
|
53
58
|
requirements: []
|
54
59
|
rubyforge_project:
|
55
|
-
rubygems_version: 1.8.
|
60
|
+
rubygems_version: 1.8.23
|
56
61
|
signing_key:
|
57
62
|
specification_version: 3
|
58
63
|
summary: ! '["This is a simple client library for OML which does not use liboml2 and
|