oml4r 2.9.1 → 2.9.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|