oml4r 2.9.0.2 → 2.9.1

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ .project
@@ -1,4 +1,4 @@
1
- Copyright 2009-2012 National ICT Australia (NICTA), Australia
1
+ Copyright 2009-2013 National ICT Australia (NICTA), Australia
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -31,42 +31,50 @@ Usage
31
31
 
32
32
  ### Initialisation, Injection and Tear-down
33
33
 
34
- OML4R::init(ARGV, {
34
+ OML4R::init(ARGV,
35
35
  :appName => 'oml4rSimpleExample',
36
- :expID => 'foo',
36
+ :domain => 'foo',
37
37
  :nodeID => 'n1',
38
- :omlServer => 'file:-'}
39
38
  )
40
- MyMP.inject("hello", 13, 37.)
39
+ MyMP.inject("hello", 13, 37.1)
41
40
  OML4R::close()
41
+
42
+ ### Multiple Channels
42
43
 
43
- ### Real example
44
-
45
- See examples files oml4r-simple-example.rb and oml4r-wlanconfig.rb.
44
+ It is sometimes desirable to send different measurement points to different collectors. OML4R supports
45
+ this with the 'channel' abstraction.
46
46
 
47
+ class A_MP < OML4R::MPBase
48
+ name :a
49
+ channel :default
50
+
51
+ param :a_val, :type => :int32
52
+ end
47
53
 
48
- License
49
- -------
54
+ class B_MP < OML4R::MPBase
55
+ name :b
56
+ channel :archive
57
+ channel :default
58
+
59
+ param :b_val, :type => :int32
60
+ end
61
+
62
+ OML4R::init(ARGV,
63
+ :appName => 'doubleAgent',
64
+ :domain => 'foo'
65
+ )
66
+ OML4R::create_channel(:archive, 'file:/tmp/archive.log')
50
67
 
51
- Copyright 2009-2012 National ICT Australia (NICTA), Australia
68
+ Setting the command line flag '--oml-collect' will define a ':default' channel. Any additional channels
69
+ need to be declared with 'OML4R::create_channel' which takes two arguments, the name of the channel
70
+ and the destination for the measurement stream. The above example defines an 'archive' channel
71
+ which is being collected in the local '/tmp/archive.log' file.
52
72
 
53
- Permission is hereby granted, free of charge, to any person obtaining a copy
54
- of this software and associated documentation files (the "Software"), to deal
55
- in the Software without restriction, including without limitation the rights
56
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57
- copies of the Software, and to permit persons to whom the Software is
58
- furnished to do so, subject to the following conditions:
73
+ Please note that by declaring a specific channel, every MP needs at least one channel declaration.
59
74
 
60
- The above copyright notice and this permission notice shall be included in
61
- all copies or substantial portions of the Software.
75
+ ### Real example
62
76
 
63
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
69
- THE SOFTWARE.
77
+ See examples files oml4r-simple-example.rb and oml4r-wlanconfig.rb.
70
78
 
71
79
  [oml-text]: http://oml.mytestbed.net/projects/oml/wiki/Description_of_Text_protocol
72
80
  [oml4r-rubygem]: https://rubygems.org/gems/oml4r/
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2009 - 2012 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-simple-example.rb
8
+ #
9
+ # == Description
10
+ #
11
+ # A very simple straightforward example of OML4R.
12
+ #
13
+ require 'rubygems'
14
+ require 'oml4r'
15
+
16
+ # Define your own Measurement Points
17
+ class SinMP < OML4R::MPBase
18
+ name :sin
19
+ #channel :default
20
+
21
+ param :label
22
+ param :angle, :type => :int32
23
+ param :value, :type => :double
24
+ end
25
+
26
+ class CosMP < OML4R::MPBase
27
+ name :cos
28
+ # channel :ch1
29
+ # channel :default
30
+
31
+ param :label
32
+ param :value, :type => :double
33
+ end
34
+
35
+ # Initialise the OML4R module for your application
36
+ opts = {:appName => 'oml4rSimpleExample',
37
+ :domain => 'foo',
38
+ :collect => 'file:-'} # Server could also be tcp:host:port
39
+ #
40
+ #OML4R::create_channel(:ch1, 'file:/tmp/foo.log')
41
+
42
+ begin
43
+ OML4R::init(ARGV, opts)
44
+ rescue OML4R::MissingArgumentException => mex
45
+ $stderr.puts mex
46
+ exit
47
+ end
48
+
49
+ # Now collect and inject some measurements
50
+ 500.times do |i|
51
+ sleep 0.5
52
+ angle = 15 * i
53
+ SinMP.inject("label_#{angle}", angle, Math.sin(angle))
54
+ CosMP.inject("label_#{angle}", Math.cos(angle))
55
+ end
56
+
57
+ # Don't forget to close when you are finished
58
+ OML4R::close()
59
+
60
+ # vim: sw=2
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2010-2012 National ICT Australia (NICTA), Australia
2
+ # Copyright (c) 2010-2013 National ICT Australia (NICTA), Australia
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
30
30
  # its output (= measurements), and finally pass them to OML4R, which will in
31
31
  # turn either store them in a local file or forward them to the OML Server.
32
32
  #
33
+ require "rubygems"
33
34
  require "oml4r"
34
35
 
35
36
  APPNAME = "wlanconfig"
@@ -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"
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2009 - 2012 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
+ # = test_types.rb
8
+ #
9
+ # == Description
10
+ #
11
+ # Testing blobs and long strings. Should really go into a test suite.
12
+ #
13
+ require 'rubygems'
14
+ require 'oml4r'
15
+
16
+ # Define your own Measurement Points
17
+ class TestMP < OML4R::MPBase
18
+ name :test
19
+ #channel :default
20
+
21
+ param :text
22
+ param :blob, :type => :blob
23
+ end
24
+
25
+ # Initialise the OML4R module for your application
26
+ opts = {:appName => 'test_types',
27
+ :domain => 'foo', :nodeID => 'n1',
28
+ :collect => 'file:-'}
29
+
30
+ OML4R::init(ARGV, opts)
31
+
32
+ # Now collect and inject some measurements
33
+ blob = ""
34
+ 30.times {|i| blob << i}
35
+ TestMP.inject(%{tab new line
36
+ another two
37
+
38
+ and that's it}, blob)
39
+
40
+ # Don't forget to close when you are finished
41
+ OML4R::close()
42
+
43
+ # vim: sw=2
@@ -0,0 +1,240 @@
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
+ # = benchmark.rb
8
+ #
9
+ # == Description
10
+ #
11
+ # Provides convenience functions to monitor long running services and
12
+ # report performance metrics through OML
13
+ #
14
+ require 'oml4r'
15
+
16
+ module OML4R
17
+ #
18
+ # Monitor the CPU consumption of a block and report it to
19
+ # OML
20
+ #
21
+ class Benchmark
22
+
23
+ def self.bm(label, opts = {}, &block)
24
+ inst = self.new(label, opts)
25
+ inst.measure(&block) if block
26
+ inst
27
+ end
28
+
29
+ # Measure execution of 'block'. Benchmarking is assumed
30
+ # to be finished when block finished. Don't attempt to
31
+ # call again
32
+ #
33
+ def measure(&block)
34
+ raise "Missing block" unless block
35
+ start
36
+ block.arity == 0 ? block.call() : block.call(self)
37
+ _stop
38
+ end
39
+
40
+ # Execute block and add execution time to overall
41
+ # measurements. Can be called multiple time. Need
42
+ # to finally call '#stop' to report overall stats.
43
+ #
44
+ def task(&block)
45
+ raise "Missing block" unless block
46
+ resume
47
+ block.arity == 0 ? block.call() : block.call(self)
48
+ pause
49
+ end
50
+
51
+ def start()
52
+ @lock.synchronize do
53
+ raise "Don't call this directly" if @running
54
+ @running = true
55
+ end
56
+
57
+ if @monitor_interval > 0
58
+ Thread.new do
59
+ while @running
60
+ sleep @monitor_interval
61
+ _report()
62
+ end
63
+ end
64
+ end
65
+ @t0, r0 = Process.times, Time.now
66
+ @t1 = @t0
67
+ @r1 = @r0 = r0.to_f
68
+ end
69
+
70
+ def pause()
71
+ t, r = Process.times, Time.now
72
+ @lock.synchronize do
73
+ return unless @running
74
+ return if @paused
75
+ @paused = true
76
+
77
+ @paused_t = t
78
+ @paused_r = r.to_f
79
+ end
80
+ end
81
+
82
+ def resume()
83
+ @lock.synchronize do
84
+ unless @running
85
+ # hasn't been kicked off yet
86
+ start
87
+ return
88
+ end
89
+
90
+ return unless @paused
91
+ t, r = Process.times, Time.now
92
+ off_u = t.utime - @paused_t.utime
93
+ off_s = t.stime - @paused_t.stime
94
+ off_t = r.to_f - @paused_r
95
+ @t0 = Struct::Tms.new(@t0.utime + off_u, @t0.stime + off_s)
96
+ @r0 = @r0 + off_t
97
+ if @t1
98
+ @t1 = Struct::Tms.new(@t1.utime + off_u, @t1.stime + off_s)
99
+ @r1 = @r1 + off_t
100
+ end
101
+ @paused = false
102
+ end
103
+ end
104
+
105
+ def stop
106
+ @lock.synchronize do
107
+ return unless @running
108
+ end
109
+ _stop
110
+ end
111
+
112
+ # Push out an intermediate report. Does
113
+ # nothing if already finished.
114
+ #
115
+ # NOTE: Not thread safe
116
+ #
117
+ def report(label = nil)
118
+ return unless @running
119
+ _report(label)
120
+ end
121
+
122
+ # Report a step in the processing. Used to calculate a
123
+ # progress rate
124
+ #
125
+ # NOTE: Not thread safe
126
+ #
127
+ def step(cnt = 1)
128
+ @step_cnt += cnt
129
+ end
130
+
131
+ private
132
+
133
+ class BenchmarkMP < OML4R::MPBase
134
+ name :benchmark
135
+ #channel :default
136
+
137
+ param :label
138
+ param :note
139
+ param :is_absolute, :type => :boolean
140
+ param :is_final, :type => :boolean
141
+ param :step_cnt, :type => :int32
142
+ param :rate_real, :type => :double
143
+ param :rate_usys, :type => :double
144
+ param :time_wall, :type => :double
145
+ param :time_user, :type => :double
146
+ param :time_sys, :type => :double
147
+ end
148
+
149
+ def initialize(name, opts)
150
+ @name = name
151
+ @running = false
152
+ @paused = false
153
+
154
+ @monitor_interval = opts[:periodic] || -1
155
+ @step_cnt = 0
156
+ @step_cnt1 = 0
157
+
158
+ @lock = Monitor.new
159
+ @first_report = true
160
+ end
161
+
162
+ def _stop
163
+ _report('done', true)
164
+ @lock.synchronize do
165
+ @running = false
166
+ end
167
+ end
168
+
169
+ def _report(label = '-', is_final = false)
170
+ t, r = Process.times, Time.now
171
+ @lock.synchronize do
172
+ if @paused
173
+ # report ONCE while paused
174
+ return if @paused_r == @last_paused_r
175
+ @last_paused_r = @paused_r
176
+ t = @paused_t
177
+ r = @paused_r
178
+ end
179
+ r = r.to_f
180
+ _inject(label, true, is_final, t, r, @t0, @r0, @step_cnt)
181
+ unless (is_final && @first_report)
182
+ # don't report incremental on final if this would be the first incr
183
+ _inject(label, false, is_final, t, r, @t1, @r1, @step_cnt - @step_cnt1)
184
+ end
185
+ @t1 = t
186
+ @r1 = r
187
+ @step_cnt1 = @step_cnt
188
+ @first_report = false
189
+ end
190
+ end
191
+
192
+ def _inject(label, is_absolute, is_final, t1, r1, t0, r0, step_cnt)
193
+ d_u = t1.utime - t0.utime
194
+ d_s = t1.stime - t0.stime
195
+ d_t = r1 - r0
196
+ #puts "INJECT0 #{d_u} #{d_s} #{d_t}"
197
+ return if (d_t <= 0 || (d_s + d_u) <= 0)
198
+ BenchmarkMP.inject @name, label, is_absolute, is_final, step_cnt, step_cnt / d_t, step_cnt / (d_u + d_s), d_t, d_u, d_s
199
+ end
200
+ end
201
+ end
202
+
203
+ if __FILE__ == $0
204
+ opts = {
205
+ :appName => 'bm_test',
206
+ :domain => 'foo',
207
+ :nodeID => 'n1',
208
+ :collect => 'file:-'
209
+ }
210
+ OML4R::init(ARGV, opts)
211
+
212
+ bm_i = OML4R::Benchmark.bm('inner_test', periodic: 0.1)
213
+ OML4R::Benchmark.bm('test', periodic: 0.1) do |bm|
214
+ 20.times do |i|
215
+ 10.times do
216
+ "a" * 1_000_000
217
+ bm.step
218
+ end
219
+
220
+ bm_i.task do
221
+ 10.times do
222
+ "a" * 1_000_000
223
+ bm_i.step
224
+ end
225
+ end
226
+
227
+ sleep 0.02
228
+ if i == 10
229
+ bm.pause
230
+ sleep 2
231
+ bm.resume
232
+ end
233
+ #bm.report()
234
+ end
235
+ end
236
+ bm_i.stop
237
+ OML4R::close()
238
+ puts 'done'
239
+ end
240
+
@@ -0,0 +1,11 @@
1
+ # Copyright (c) 2009 - 2012 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
+ module OML4R
8
+ VERSION = "2.9.1"
9
+ VERSION_STRING = "OML4R Client V#{VERSION}"
10
+ COPYRIGHT = "Copyright 2009-2013, NICTA"
11
+ end
data/lib/oml4r.rb CHANGED
@@ -1,24 +1,8 @@
1
- #
2
- # Copyright 2009-2012 National ICT Australia (NICTA), Australia
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
1
+ # Copyright (c) 2009 - 2012 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
+ # ------------------
22
6
  #
23
7
  # = oml4r.rb
24
8
  #
@@ -34,21 +18,28 @@ require 'monitor'
34
18
  require 'thread'
35
19
  require 'optparse'
36
20
 
21
+ require 'oml4r/version'
22
+
37
23
  #
38
24
  # This is the OML4R module, which should be required by ruby applications
39
25
  # that want to collect measurements via OML
40
26
  #
41
27
  module OML4R
42
28
 
43
- VERSION = "2.9.0.2"
44
- VERSION_STRING = "OML4R Client V#{VERSION}"
45
- COPYRIGHT = "Copyright 2009-2012, NICTA"
46
29
  DEF_SERVER_PORT = 3003
30
+ DEF_PROTOCOL = 3
47
31
 
48
- PROTOCOL = 3
49
- @loglevel = 0
50
- class << self; attr_accessor :loglevel; end
51
-
32
+ # Overwrite the default logger
33
+ #
34
+ # @param logger Needs to respond to 'debug', 'info', ...
35
+ #
36
+ def self.logger=(logger)
37
+ @@logger = logger
38
+ end
39
+
40
+ class OML4RExeption < Exception; end
41
+ class MissingArgumentException < OML4RExeption; end
42
+ class ArgumentMismatchException < OML4RExeption; end
52
43
  #
53
44
  # Measurement Point Class
54
45
  # Ruby applications using this module should sub-class this MPBase class
@@ -77,9 +68,9 @@ module OML4R
77
68
  # Returns the definition of this MP
78
69
  def self.__def__()
79
70
  unless (defs = @@defs[self])
80
- defs = @@defs[self] = {}
81
- defs[:p_def] = []
82
- defs[:seq_no] = 0
71
+ defs = @@defs[self] = {}
72
+ defs[:p_def] = []
73
+ defs[:seq_no] = 0
83
74
  end
84
75
  defs
85
76
  end
@@ -105,9 +96,12 @@ module OML4R
105
96
  o = opts.dup
106
97
  o[:name] = name
107
98
  o[:type] ||= :string
108
- if o[:type] == :long
109
- $stderr.puts "WARN :long is deprecated use, :int32 instead"
110
- o[:type] = :int32
99
+ case o[:type]
100
+ when :long
101
+ OML4R.logger.warn ":long is deprecated use, :int32 instead"
102
+ o[:type] = :int32
103
+ when :boolean
104
+ o[:type] = :int32 # TODO: Hopefully we can remove this soon
111
105
  end
112
106
  __def__()[:p_def] << o
113
107
  nil
@@ -124,23 +118,34 @@ module OML4R
124
118
  # definition of this Measurement Point
125
119
  defs = __def__()
126
120
  pdef = defs[:p_def]
121
+ types = defs[:types]
127
122
  if args.size != pdef.size
128
- raise "OML4R: Size mismatch between the measurement (#{args.size}) and the MP definition (#{pdef.size})!"
123
+ raise ArgumentMismatchException.new "OML4R: Size mismatch between the measurement (#{args.size}) and the MP definition (#{pdef.size})!"
129
124
  end
130
125
 
131
126
  # Now prepare the measurement...
132
127
  t = Time.now - @@start_time
133
128
  a = []
134
129
  a << (defs[:seq_no] += 1)
135
- args.each do |arg|
136
- a << arg
130
+ args.each_with_index do |arg, i|
131
+ case types[i]
132
+ when :string
133
+ # Escape tabs and newlines
134
+ arg = arg.to_s.gsub("\n", "\\n").gsub("\t", "\\t")
135
+ when :boolean
136
+ # boolean
137
+ arg = arg ? 1 : 0
138
+ when :blob
139
+ arg = [arg].pack("m")
140
+ end
141
+ a << arg
137
142
  end
138
143
  # ...and inject it!
139
144
  msg = a.join("\t")
140
145
  @@channels[self].each do |ca|
141
- channel = ca[0]
142
- index = ca[1]
143
- channel.send "#{t}\t#{index}\t#{msg}"
146
+ channel = ca[0]
147
+ index = ca[1]
148
+ channel.send "#{t}\t#{index}\t#{msg}"
144
149
  end
145
150
  args
146
151
  end
@@ -154,24 +159,28 @@ module OML4R
154
159
  def self.__freeze__(appName, start_time)
155
160
  return if @@frozen
156
161
  @@frozen = true
162
+ # create type array for easier processing in inject
163
+ @@defs.each do |name, descr|
164
+ descr[:types] = descr[:p_def].map {|h| h[:type]}
165
+ end
166
+
157
167
  # replace channel names with channel object
158
168
  self.each_mp do |klass, defs|
159
- cna = @@channels[klass] || []
160
- $stderr.puts "DEBUG '#{cna.inspect}', '#{klass}'" if OML4R.loglevel > 0
161
- ca = cna.collect do |cname, domain|
162
- # return it in an array as we need to add the channel specific index
163
- [Channel[cname.to_sym, domain.to_sym]]
164
- end
165
- $stderr.puts "DEBUG Using channels '#{ca.inspect}" if OML4R.loglevel > 0
166
- @@channels[klass] = ca.empty? ? [[Channel[]]] : ca
169
+ cna = @@channels[klass] || []
170
+ OML4R.logger.debug "'#{cna.inspect}', '#{klass}'"
171
+ ca = cna.collect do |cname, domain|
172
+ # return it in an array as we need to add the channel specific index
173
+ [Channel[cname.to_sym, domain.to_sym]]
174
+ end
175
+ OML4R.logger.debug "Using channels '#{ca.inspect}"
176
+ @@channels[klass] = ca.empty? ? [[Channel[]]] : ca
167
177
  end
168
178
  @@start_time = start_time
169
-
170
179
  end
171
180
 
172
181
  def self.__unfreeze__()
173
182
  self.each_mp do |klass, defs|
174
- defs[:seq_no] = 0
183
+ defs[:seq_no] = 0
175
184
  end
176
185
  @@channels = {}
177
186
  @@start_time = nil
@@ -186,16 +195,16 @@ module OML4R
186
195
 
187
196
  # Do some sanity checks...
188
197
  unless (mp_name = defs[:name])
189
- raise "Missing 'name' declaration for '#{self}'"
198
+ raise MissingArgumentException.new "Missing 'name' declaration for '#{self}'"
190
199
  end
191
200
  unless (name_prefix.nil?)
192
- mp_name = "#{name_prefix}_#{mp_name}"
201
+ mp_name = "#{name_prefix}_#{mp_name}"
193
202
  end
194
203
 
195
204
  @@channels[self].each do |ca|
196
- $stderr.puts "DEBUG Setting up channel '#{ca.inspect}" if OML4R.loglevel > 0
197
- index = ca[0].send_schema(mp_name, defs[:p_def])
198
- ca << index
205
+ OML4R.logger.debug "Setting up channel '#{ca.inspect}"
206
+ index = ca[0].send_schema(mp_name, defs[:p_def])
207
+ ca << index
199
208
  end
200
209
  end
201
210
  end # class MPBase
@@ -215,12 +224,12 @@ module OML4R
215
224
  # - & block = a block which defines the additional application-specific arguments
216
225
  #
217
226
  def self.init(argv, opts = {}, &block)
218
- $stderr.puts("INFO #{VERSION_STRING} [Protocol V#{PROTOCOL}] #{COPYRIGHT}")
227
+ OML4R#{VERSION_STRING} [#{COPYRIGHT}")
219
228
 
220
229
  if d = (ENV['OML_EXP_ID'] || opts[:expID])
221
230
  # XXX: It is still too early to complain about that. We need to be sure
222
231
  # of the nomenclature before making user-visible changes.
223
- $stderr.puts "WARN opts[:expID] and ENV['OML_EXP_ID'] are getting deprecated; please use opts[:domain] or ENV['OML_DOMAIN'] instead"
232
+ OML4R.logger.warn "opts[:expID] and ENV['OML_EXP_ID'] are getting deprecated; please use opts[:domain] or ENV['OML_DOMAIN'] instead"
224
233
  opts[:domain] ||= d
225
234
  end
226
235
  domain ||= ENV['OML_DOMAIN'] || opts[:domain]
@@ -237,16 +246,17 @@ module OML4R
237
246
  # raise 'OML4R: :app is not a valid option. Do you mean :appName?'
238
247
  #end
239
248
  appName = opts[:appName] || opts[:app]
249
+ protocol = opts[:protocol] = DEF_PROTOCOL
240
250
 
241
251
  if ENV['OML_URL'] || opts[:omlURL] || opts[:url]
242
- raise 'ERROR neither OML_URL, :omlURL nor :url are valid. Do you mean OML_COLLECT or :omlCollect?'
252
+ raise MissingArgumentException.new 'neither OML_URL, :omlURL nor :url are valid. Do you mean OML_COLLECT or :omlCollect?'
243
253
  end
244
254
  if ENV['OML_SERVER'] || opts[:omlServer]
245
- $stderr.puts "WARN opts[:omlServer] and ENV['OML_SERVER'] are getting deprecated; please use opts[:collect] or ENV['OML_COLLECT'] instead"
255
+ OML4R.logger.warn "opts[:omlServer] and ENV['OML_SERVER'] are getting deprecated; please use opts[:collect] or ENV['OML_COLLECT'] instead"
246
256
  end
247
257
  omlCollectUri = ENV['OML_COLLECT'] || ENV['OML_SERVER'] || opts[:collect] || opts[:omlServer]
248
258
  noop = opts[:noop] || false
249
- omlConfigFile = nil
259
+
250
260
 
251
261
  # Create a new Parser for the command line
252
262
  op = OptionParser.new
@@ -256,61 +266,69 @@ module OML4R
256
266
  op.on("--oml-id id", "Name to identify this app instance [#{nodeID || 'undefined'}]") { |name| nodeID = name }
257
267
  op.on("--oml-domain domain", "Name of experimental domain [#{domain || 'undefined'}] *EXPERIMENTAL*") { |name| domain = name }
258
268
  op.on("--oml-collect uri", "URI of server to send measurements to") { |u| omlCollectUri = u }
259
- op.on("--oml-log-level l", "Log level used (info: 0 .. debug: 1)") { |l| OML4R.loglevel = l.to_i }
269
+ op.on("--oml-protocol p", "Protocol number [#{OML4R::DEF_PROTOCOL}]") { |l| protocol = l.to_i }
270
+ op.on("--oml-log-level l", "Log level used (info: 1 .. debug: 0)") { |l| OML4R.logger.level = l.to_i }
260
271
  op.on("--oml-noop", "Do not collect measurements") { noop = true }
261
- op.on("--oml-config file", "File holding OML configuration parameters") { |f| omlConfigFile = f }
262
272
  op.on("--oml-exp-id domain", "Obsolescent equivalent to --oml-domain domain") { |name|
263
273
  domain = name
264
- $stderr.puts "WARN Option --oml-exp-id is getting deprecated; please use '--oml-domain #{domain}' instead"
274
+ OML4R.logger.warn "Option --oml-exp-id is getting deprecated; please use '--oml-domain #{domain}' instead"
265
275
  }
266
276
  op.on("--oml-file localPath", "Obsolescent equivalent to --oml-collect file:localPath") { |name|
267
277
  omlCollectUri = "file:#{name}"
268
- $stderr.puts "WARN Option --oml-file is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
278
+ OML4R.logger.warn "Option --oml-file is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
269
279
  }
270
280
  op.on("--oml-server uri", "Obsolescent equivalent to --oml-collect uri") {|u|
271
281
  omlCollectUri = u
272
- $stderr.puts "WARN Option --oml-server is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
282
+ OML4R.logger.warn "Option --oml-server is getting deprecated; please use '--oml-collect #{omlCollectUri}' instead"
273
283
  }
274
284
  op.on_tail("--oml-help", "Show this message") { $stderr.puts op; exit }
275
285
  # XXX: This should be set by the application writer, not the command line
276
286
  #op.on("--oml-appid APPID", "Application ID for OML [#{appName || 'undefined'}] *EXPERIMENTAL*") { |name| appID = name }
277
287
 
278
- # Set a default collection URI if nothing has been specified
279
- omlCollectUri ||= "file:#{appName}_#{nodeID}_#{domain}_#{Time.now.strftime("%Y-%m-%dt%H.%M.%S%z")}"
280
-
281
288
  # Now parse the command line
282
- $stderr.puts "DEBUG ARGV:>>> #{argv.inspect}" if OML4R.loglevel > 0
289
+ OML4R.logger.debug "ARGV:>>> #{argv.inspect}"
283
290
  rest = op.parse(argv)
284
291
  return if noop
285
292
 
286
- # Parameters in OML config file takes precedence
287
- unless omlConfigFile.nil?
288
- f = File.open(omlConfigFile, 'r')
289
- f.each_line do |l|
290
- d = l[/.*experiment='([^']*)/,1]
291
- domain = d if d
292
- i = l[/.*id='([^']*)/,1]
293
- nodeID = i if i
294
- u = l[/.*url='([^']*)/,1]
295
- omlCollectUri = u if u
293
+ unless nodeID
294
+ begin
295
+ # Create a default nodeID by concatinating the local hostname with the process ID
296
+ hostname = nil
297
+ begin
298
+ hostname = Socket.gethostbyname(Socket.gethostname)[0]
299
+ rescue Exception
300
+ begin
301
+ hostname = `hostname`
302
+ rescue Exception; end
296
303
  end
297
- f.close
304
+ if hostname
305
+ nodeID = "#{hostname}-#{Process.pid}"
306
+ end
307
+ end
308
+ unless nodeID
309
+ raise MissingArgumentException.new 'OML4R: Missing values for parameter :nodeID (--oml-id)'
310
+ end
298
311
  end
299
-
300
- unless domain && nodeID && appName
301
- raise 'OML4R: Missing values for parameters :domain (--oml-domain), :nodeID (--oml-id), or :appName (in code)!'
312
+
313
+ unless domain && appName
314
+ raise MissingArgumentException.new 'OML4R: Missing values for parameters :domain (--oml-domain), :nodeID (--oml-id), or :appName (in code)!'
302
315
  end
303
316
 
304
- Channel.create(:default, omlCollectUri) if omlCollectUri
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
+
320
+ create_channel(:default, omlCollectUri) if omlCollectUri
305
321
 
306
322
  # Handle the defined Measurement Points
307
323
  startTime = Time.now
308
- Channel.init_all(domain, nodeID, appName, startTime)
309
- msg = "Collection URI is #{omlCollectUri}"
310
- Object.const_defined?(:MObject) ? MObject.debug(:oml4r, msg) : $stderr.puts("INFO #{msg}")
311
-
324
+ Channel.init_all(domain, nodeID, appName, startTime, protocol)
325
+ OML4R.logger.info "Collection URI is #{omlCollectUri}"
312
326
  rest || []
313
327
  end
328
+
329
+ def self.create_channel(name, url)
330
+ Channel.create(name, url)
331
+ end
314
332
 
315
333
  #
316
334
  # Close the OML collection. This will block until all outstanding data have been sent out.
@@ -330,14 +348,16 @@ module OML4R
330
348
  class Channel
331
349
  @@channels = {}
332
350
  @@default_domain = nil
351
+
352
+
333
353
 
334
354
  def self.create(name, url, domain = :default)
335
355
  key = "#{name}:#{domain}"
336
356
  if channel = @@channels[key]
337
- if url != channel.url
338
- raise "OML4R: Channel '#{name}' already defined with different url"
339
- end
340
- return channel
357
+ if url != channel.url
358
+ raise OML4RException.new "OML4R: Channel '#{name}' already defined with different url"
359
+ end
360
+ return channel
341
361
  end
342
362
  return self._create(key, domain, url)
343
363
  end
@@ -349,15 +369,15 @@ module OML4R
349
369
 
350
370
  def self._connect(url)
351
371
  if url.start_with? 'file:'
352
- proto, fname = url.split(':')
353
- out = (fname == '-' ? $stdout : File.open(fname, "w+"))
372
+ proto, fname = url.split(':')
373
+ out = (fname == '-' ? $stdout : File.open(fname, "w+"))
354
374
  elsif url.start_with? 'tcp:'
355
- #tcp:norbit.npc.nicta.com.au:3003
356
- proto, host, port = url.split(':')
357
- port ||= DEF_SERVER_PORT
358
- out = TCPSocket.new(host, port)
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)
359
379
  else
360
- raise "OML4R: Unknown transport in server url '#{url}'"
380
+ raise OML4RException.new "OML4R: Unknown transport in server url '#{url}'"
361
381
  end
362
382
  out
363
383
  end
@@ -365,28 +385,28 @@ module OML4R
365
385
  def self.[](name = :default, domain = :default)
366
386
  key = "#{name}:#{domain}"
367
387
  unless (@@channels.key?(key))
368
- # If domain != :default and we have one for :default, create a new one
369
- if (domain != :default)
370
- if (dc = @@channels["#{name}:default"])
371
- return self._create(key, domain, dc.url)
372
- end
373
- end
374
- raise "OML4R: Unknown channel '#{name}'"
388
+ # If domain != :default and we have one for :default, create a new one
389
+ if (domain != :default)
390
+ if (dc = @@channels["#{name}:default"])
391
+ return self._create(key, domain, dc.url)
392
+ end
393
+ end
394
+ raise OML4RException.new "OML4R: Unknown channel '#{name}'"
375
395
  end
376
396
  @@channels[key]
377
397
  end
378
398
 
379
- def self.init_all(domain, nodeID, appName, startTime)
399
+ def self.init_all(domain, nodeID, appName, startTime, protocol)
380
400
  @@default_domain = domain
381
401
 
382
402
  MPBase.__freeze__(appName, startTime)
383
403
 
384
404
  # send channel header
385
- @@channels.values.each { |c| c.init(nodeID, appName, startTime) }
405
+ @@channels.values.each { |c| c.init(nodeID, appName, startTime, protocol) }
386
406
 
387
407
  # send schema definitions
388
408
  MPBase.each_mp do |klass, defs|
389
- klass.__print_meta__(appName)
409
+ klass.__print_meta__(appName)
390
410
  end
391
411
 
392
412
  MPBase.__useOML__()
@@ -403,12 +423,13 @@ module OML4R
403
423
  def send_schema(mp_name, pdefs) # defs[:p_def]
404
424
  # Build the schema and send it
405
425
  @index += 1
406
- line = ['schema:', @index, mp_name]
426
+ #line = ['schema:', @index, mp_name]
427
+ line = [@index, mp_name]
407
428
  pdefs.each do |d|
408
- line << "#{d[:name]}:#{d[:type]}"
429
+ line << "#{d[:name]}:#{d[:type]}"
409
430
  end
410
431
  msg = line.join(' ')
411
- @header << msg
432
+ @schemas << msg
412
433
  @index
413
434
  end
414
435
 
@@ -416,8 +437,8 @@ module OML4R
416
437
  @queue.push msg
417
438
  end
418
439
 
419
- def init(nodeID, appName, startTime)
420
- send_protocol_header(nodeID, appName, startTime)
440
+ def init(nodeID, appName, startTime, protocol)
441
+ @nodeID, @appName, @startTime, @protocol = nodeID, appName, startTime, protocol
421
442
  end
422
443
 
423
444
  def close()
@@ -431,67 +452,82 @@ module OML4R
431
452
  @url = url
432
453
  @out = out_channel
433
454
  @index = 0
434
- @header = []
455
+ @schemas = []
435
456
  @header_sent = false
436
457
  @queue = Queue.new
437
458
  start_runner
438
459
  end
439
460
 
440
461
 
441
- def send_protocol_header(nodeID, appName, startTime)
442
- @header << "protocol: #{PROTOCOL}"
462
+ def _send_protocol_header(stream)
463
+ header = []
464
+ header << "protocol: #{@protocol}"
465
+ header << "content: text"
443
466
  d = (@domain == :default) ? @@default_domain : @domain
444
- raise "Missing domain name" unless d
445
- @header << "experiment-id: #{d}"
446
- @header << "start_time: #{startTime.tv_sec}"
447
- @header << "sender-id: #{nodeID}"
448
- @header << "app-name: #{appName}"
449
- @header << "content: text"
467
+ raise MissingArgumentException.new "Missing domain name" unless d
468
+ case @protocol || OML4R::DEF_PROTOCOL
469
+ when 3
470
+ header << "experiment-id: #{d}"
471
+ header << "start_time: #{@startTime.tv_sec}"
472
+ header << "sender-id: #{@nodeID}"
473
+ header << "app-name: #{@appName}"
474
+ @schemas.each do |s|
475
+ header << "schema: #{s}"
476
+ end
477
+ header << ""
478
+ when 4
479
+ i = 0
480
+ header << ""
481
+ header << "0\t0\t#{i += 1}\t.\texperiment-id\t#{d}"
482
+ header << "0\t0\t#{i += 1}\t.\tstart_time\t#{@startTime.tv_sec}"
483
+ header << "0\t0\t#{i += 1}\t.\tsender-id\t#{@nodeID}"
484
+ header << "0\t0\t#{i += 1}\t.\tapp-name\t#{@appName}"
485
+ @schemas.each do |s|
486
+ header << "0\t0\t#{i += 1}\t.\tschema\t#{s}"
487
+ end
488
+
489
+ else
490
+ raise OML4RException.new "Unsupported protocol #{@protocol}"
491
+ end
492
+ stream.puts header
450
493
  end
451
494
 
452
495
  def start_runner
453
496
  header_sent = false
454
497
  @runner = Thread.new do
455
- active = true
456
- begin
457
- while (active)
458
- msg = @queue.pop
459
- active = !msg.nil?
460
- if !@queue.empty?
461
- ma = [msg]
462
- while !@queue.empty?
463
- msg = @queue.pop
464
- if (active = !msg.nil?)
465
- ma << msg
466
- end
467
- end
468
- msg = ma.join("\n")
469
- end
470
- #$stderr.puts ">>>>>>#{@domain}: <#{msg}>"
498
+ active = true
499
+ begin
500
+ while (active)
501
+ msg = @queue.pop
502
+ active = !msg.nil?
503
+ if !@queue.empty?
504
+ ma = [msg]
505
+ while !@queue.empty?
506
+ msg = @queue.pop
507
+ if (active = !msg.nil?)
508
+ ma << msg
509
+ end
510
+ end
511
+ msg = ma.join("\n")
512
+ end
513
+ #$stderr.puts ">>>>>>#{@domain}: <#{msg}>"
471
514
  unless msg.nil?
472
515
  _send msg
473
516
  end
474
- end
475
- @out.close
476
- @out = nil
477
- rescue Exception => ex
478
- msg = "Exception while sending message to channel '#{@url}' (#{ex.class})"
479
- Object.const_defined?(:MObject) ? MObject.warn(:oml4r, msg) : $stderr.puts("INFO #{msg}")
480
- end
481
- info "Channel #{url} closed"
517
+ end
518
+ @out.close unless @out == $stdout
519
+ @out = nil
520
+ rescue Exception => ex
521
+ OML4R.logger.warn "Exception while sending message to channel '#{@url}' (#{ex})"
522
+ end
523
+ OML4R.logger.info "Channel #{url} closed"
482
524
  end
483
525
  end
484
526
 
485
- def info(msg)
486
- Object.const_defined?(:MObject) ? MObject.warn(:oml4r, msg) : $stderr.puts("INFO #{msg}")
487
- end
488
-
489
527
  def _send(msg)
490
528
  begin
491
529
  unless @header_sent
492
- h = "#{@header.join("\n")}\n\n"
493
- $stderr.puts "DEBUG '#{h}'" if OML4R.loglevel > 3
494
- @out.puts h
530
+ _send_protocol_header(@out)
495
531
  @header_sent = true
496
532
  end
497
533
  @out.puts msg
@@ -499,16 +535,16 @@ module OML4R
499
535
 
500
536
  rescue Errno::EPIPE
501
537
  # Trying to reconnect
502
- info "Trying to reconnect to '#{@url}'"
538
+ OML4R.logger.info "Trying to reconnect to '#{@url}'"
503
539
  loop do
504
540
  sleep 5
505
541
  begin
506
542
  @out = self.class._connect(@url)
507
543
  @header_sent = false
508
- info "Reconnected to '#{@url}'"
544
+ OML4R.logger.info "Reconnected to '#{@url}'"
509
545
  return _send(msg)
510
546
  rescue Errno::ECONNREFUSED => ex
511
- info "Exception while reconnect '#{@url}' (#{ex.class})"
547
+ OML4R.logger.warn "Exception while reconnect '#{@url}' (#{ex.class})"
512
548
  end
513
549
  #Errno::ECONNREFUSED
514
550
  end
@@ -516,7 +552,23 @@ module OML4R
516
552
  end
517
553
 
518
554
  end # Channel
519
-
555
+
556
+ require 'logger'
557
+
558
+ class Logger < ::Logger
559
+ def format_message(severity, time, progname, message)
560
+ "%5s oml4r: %s\n" % [severity, message]
561
+ end
562
+ end
563
+
564
+ @@logger = Logger.new(STDERR)
565
+ @@logger.level = ::Logger::INFO
566
+
567
+ def self.logger
568
+ @@logger
569
+ end
570
+
571
+
520
572
  end # module OML4R
521
573
 
522
574
  # vim: sw=2
data/oml4r.gemspec CHANGED
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/oml4r.rb', __FILE__)
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "oml4r/version"
3
5
 
4
6
  Gem::Specification.new do |gem|
5
7
  gem.authors = ["NICTA"]
@@ -10,18 +12,7 @@ Gem::Specification.new do |gem|
10
12
 
11
13
  # ls-files won't work in VPATH builds;
12
14
  # plus, we want lib/oml4r.rb rather than lib/oml4r.rb.in
13
- #gem.files = `git ls-files`.split($\)
14
- gem.files = [
15
- ".yardopts",
16
- "Gemfile",
17
- "LICENSE",
18
- "README.md",
19
- "Rakefile",
20
- "lib/oml4r.rb",
21
- "lib/oml4r/oml4r-simple-example.rb",
22
- "lib/oml4r/oml4r-wlanconfig.rb",
23
- "oml4r.gemspec",
24
- ]
15
+ gem.files = `git ls-files`.split($\)
25
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
26
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
27
18
  gem.name = "oml4r"
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.0.2
4
+ version: 2.9.1
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-03-14 00:00:00.000000000 Z
12
+ date: 2013-04-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! '["Simple OML client library for Ruby"]'
15
15
  email:
@@ -18,14 +18,18 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - .yardopts
21
+ - .gitignore
22
22
  - Gemfile
23
- - LICENSE
23
+ - LICENSE.txt
24
24
  - README.md
25
25
  - Rakefile
26
+ - examples/oml4r-simple-example.rb
27
+ - examples/oml4r-wlanconfig.rb
28
+ - examples/oml4r-zabbix.rb
29
+ - examples/test_types.rb
26
30
  - lib/oml4r.rb
27
- - lib/oml4r/oml4r-simple-example.rb
28
- - lib/oml4r/oml4r-wlanconfig.rb
31
+ - lib/oml4r/benchmark.rb
32
+ - lib/oml4r/version.rb
29
33
  - oml4r.gemspec
30
34
  homepage: http://oml.mytestbed.net
31
35
  licenses:
@@ -48,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
52
  version: '0'
49
53
  requirements: []
50
54
  rubyforge_project:
51
- rubygems_version: 1.8.23
55
+ rubygems_version: 1.8.24
52
56
  signing_key:
53
57
  specification_version: 3
54
58
  summary: ! '["This is a simple client library for OML which does not use liboml2 and
data/.yardopts DELETED
@@ -1,2 +0,0 @@
1
- --title OML4R
2
- lib/*.rb
@@ -1,69 +0,0 @@
1
- #
2
- # Copyright (c) 2012 National ICT Australia (NICTA), Australia
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- #
23
- # = oml4r-simple-example.rb
24
- #
25
- # == Description
26
- #
27
- # A very simple straightforward example of OML4R.
28
- #
29
- require 'oml4r'
30
-
31
- # Define your own Measurement Points
32
- class SinMP < OML4R::MPBase
33
- name :sin
34
- #channel :default
35
-
36
- param :label
37
- param :angle, :type => :int32
38
- param :value, :type => :double
39
- end
40
-
41
- class CosMP < OML4R::MPBase
42
- name :cos
43
- # channel :ch1
44
- # channel :default
45
-
46
- param :label
47
- param :value, :type => :double
48
- end
49
-
50
- # Initialise the OML4R module for your application
51
- opts = {:appName => 'oml4rSimpleExample',
52
- :expID => 'foo', :nodeID => 'n1',
53
- :omlServer => 'file:-'} # Server could also be tcp:host:port
54
- # OML4R::create_channel(:default, 'file:-')
55
-
56
- OML4R::init(ARGV, opts)
57
-
58
- # Now collect and inject some measurements
59
- 5.times do |i|
60
- sleep 0.5
61
- angle = 15 * i
62
- SinMP.inject("label_#{angle}", angle, Math.sin(angle))
63
- CosMP.inject("label_#{angle}", Math.cos(angle))
64
- end
65
-
66
- # Don't forget to close when you are finished
67
- OML4R::close()
68
-
69
- # vim: sw=2