16 | | For this example, the CSV File used is attached here |
| 16 | For this example, the CSV File used is attached here (wimaxss.csv) |
| 17 | |
| 18 | Each of the fields has been taken as a separate measurement point for this example. |
| 19 | |
| 20 | == 3. Write OML4R application Script and save it on VM == |
| 21 | |
| 22 | === 3.1 Define a class of measurement point variables === |
| 23 | |
| 24 | This is based on the number and type of the fields in the CSV file |
| 25 | |
| 26 | {{{ |
| 27 | class MPThroughput < OML4R::MPBase |
| 28 | name :wimaxss |
| 29 | param :unixts, :type => :string |
| 30 | param :ifacemac, :type => :string |
| 31 | param :make, :type => :string |
| 32 | param :model, :type => :string |
| 33 | param :platform, :type => :string |
| 34 | param :nettype, :type => :string |
| 35 | param :netoper, :type => :string |
| 36 | param :ipaddr, :type => :string |
| 37 | param :ssid, :type => :int64 |
| 38 | param :longi, :type => :string |
| 39 | param :lat, :type => :string |
| 40 | param :geoLoc, :type => :string |
| 41 | param :metName, :type => :string |
| 42 | end |
| 43 | |
| 44 | }}} |
| 45 | |
| 46 | |
| 47 | === 3.2 Parse measurement fields === |
| 48 | |
| 49 | {{{ |
| 50 | def processOutput(output) |
| 51 | column = output.split(",") |
| 52 | puts "Each line process" |
| 53 | # Inject the measurements into OML |
| 54 | puts Integer(column[8]) |
| 55 | MPThroughput.inject("#{column[0]}", "#{column[1]}", "#{column[2]}", |
| 56 | "#{column[3]}", "#{column[4]}", "#{column[5]}", |
| 57 | "#{column[6]}", "#{column[7]}", "#{column[8]}".to_i, "#{column[9]}", "#{column[10]}", "#{column[11]}", "#{column[12]}") |
| 58 | end |
| 59 | end |
| 60 | |
| 61 | }}} |
| 62 | |
| 63 | === Specify number of lines to read === |
| 64 | |
| 65 | The log.backward() function specifies the number of lines to read while doing a file tail. In this example, it reads only 1 line from the file's history. |
| 66 | |
| 67 | {{{ |
| 68 | def start() |
| 69 | log = MyFile.new("#{@addr}") |
| 70 | log.interval = @if_num |
| 71 | log.backward(1) |
| 72 | puts "#{@if_num}" |
| 73 | log.tail { |line| print line |
| 74 | processOutput(line) |
| 75 | } |
| 76 | end |
| 77 | }}} |
| 78 | |
| 79 | |
| 80 | |
| 81 | === 3.4 The complete script is given below === |
| 82 | {{{ |
| 83 | #!/usr/local/bin/ruby |
| 84 | # |
| 85 | # This file was generated by RubyGems. |
| 86 | # |
| 87 | # The application 'oml4r' is installed as part of a gem, and |
| 88 | # this file is here to facilitate running it. |
| 89 | # |
| 90 | |
| 91 | require 'rubygems' |
| 92 | require 'oml4r' |
| 93 | require 'file-tail' |
| 94 | APPNAME = "ofstats" |
| 95 | class MPThroughput < OML4R::MPBase |
| 96 | name :wimaxss |
| 97 | param :unixts, :type => :string |
| 98 | param :ifacemac, :type => :string |
| 99 | param :make, :type => :string |
| 100 | param :model, :type => :string |
| 101 | param :platform, :type => :string |
| 102 | param :nettype, :type => :string |
| 103 | param :netoper, :type => :string |
| 104 | param :ipaddr, :type => :string |
| 105 | param :ssid, :type => :int64 |
| 106 | param :longi, :type => :string |
| 107 | param :lat, :type => :string |
| 108 | param :geoLoc, :type => :string |
| 109 | param :metName, :type => :string |
| 110 | end |
| 111 | class OFStatsWrapper |
| 112 | def initialize(args) |
| 113 | @addr = nil |
| 114 | @if_num = ' ' |
| 115 | @trema_port = ' ' |
| 116 | @trema_path = ' ' |
| 117 | @verbose = true |
| 118 | @numeric = ' ' |
| 119 | OML4R::init(args, :appName => "#{APPNAME}_wrapper", :domain => 'foo', :collect => 'file:-') { |argParser| |
| 120 | argParser.banner = "Reports OpenFlow stat measurements via OML\n\n" |
| 121 | argParser.on("-f" , "--file_path ADDRESS", "Path where output is saved"){ |address| @addr = address } |
| 122 | argParser.on("-i","--interface IFNUM","Interface number"){ |if_num| @if_num ="#{if_num.to_i()}" } |
| 123 | argParser.on("-q", "--no-quiet ","Don't show of stats output on console"){ @verbose = false } |
| 124 | argParser.on("-n", "--[no]-numeric ", "No attempt twill be made to look up symbolic names for host addresses"){ @numeric ='-n' } |
| 125 | } |
| 126 | unless @addr !=nil |
| 127 | raise "You did not specify path of file (-p option)" |
| 128 | end |
| 129 | end |
| 130 | class MyFile < File |
| 131 | include File::Tail |
| 132 | end |
| 133 | def start() |
| 134 | log = MyFile.new("#{@addr}") |
| 135 | log.interval = @if_num |
| 136 | log.backward(1) |
| 137 | puts "#{@if_num}" |
| 138 | log.tail { |line| print line |
| 139 | processOutput(line) |
| 140 | } |
| 141 | end |
| 142 | def processOutput(output) |
| 143 | column = output.split(",") |
| 144 | puts "Each line process" |
| 145 | # Inject the measurements into OML |
| 146 | puts Integer(column[8]) |
| 147 | MPThroughput.inject("#{column[0]}", "#{column[1]}", "#{column[2]}", |
| 148 | "#{column[3]}", "#{column[4]}", "#{column[5]}", |
| 149 | "#{column[6]}", "#{column[7]}", "#{column[8]}".to_i, "#{column[9]}", "#{column[10]}", "#{column[11]}", "#{column[12]}") |
| 150 | end |
| 151 | end |
| 152 | begin |
| 153 | app = OFStatsWrapper.new(ARGV) |
| 154 | app.start() |
| 155 | rescue SystemExit |
| 156 | rescue SignalException |
| 157 | puts "OFWrapper stopped." |
| 158 | rescue Exception => ex |
| 159 | puts "Error - When executing the wrapper application!" |
| 160 | puts "Error - Type: #{ex.class}" |
| 161 | puts "Error - Message: #{ex}\n\n" |
| 162 | # Uncomment the next line to get more info on errors |
| 163 | # puts "Trace - #{ex.backtrace.join("\n\t")}" |
| 164 | end |
| 165 | OML4R::close() |
| 166 | # Local Variables: |
| 167 | # mode:ruby |
| 168 | # End: |
| 169 | # vim: ft=ruby:sw=2 |
| 170 | }}} |
| 171 | |
| 172 | |
| 173 | == 4. Write OEDL Script to Run application == |
| 174 | |
| 175 | === 4.1 Specify location of CSV file on VM === |
| 176 | |
| 177 | {{{ |
| 178 | defProperty('pathfile', "/root/wimaxtest.txt", "Path to file") |
| 179 | }}} |
| 180 | |
| 181 | |
| 182 | === 4.2 Define OML Application with path on VM === |
| 183 | |
| 184 | |
| 185 | {{{ |
| 186 | defApplication('ofstats') do |app| |
| 187 | app.description = 'Simple Definition for the of-collect application' |
| 188 | # Define the path to the binary executable for this application |
| 189 | app.binary_path = '/usr/local/bin/ofcollect.rb' |
| 190 | app.defProperty('target', 'Address to output file', '-f', {:type => :string}) |
| 191 | app.defProperty("interval","Interval",'-i', {:type => :string}) |
| 192 | app.defMeasurement('wrapper_wimaxss') do |m| |
| 193 | m.defMetric(':pathtype', :string) |
| 194 | m.defMetric('throughput',:int64) |
| 195 | m.defMetric('instput',:int64) |
| 196 | end |
| 197 | end |
| 198 | }}} |
| 199 | |
| 200 | === 4.3 Create Node Group with Application === |
| 201 | |
| 202 | {{{ |
| 203 | defGroup('Source1', property.source1) do |node| |
| 204 | node.addApplication("ofstats") do |app| |
| 205 | app.setProperty('target', property.pathfile) |
| 206 | app.setProperty('interval', property.intervalcol) |
| 207 | app.measure('wrapper_wimaxss', :samples => 1) |
| 208 | end |
| 209 | end |
| 210 | }}} |
| 211 | |
| 212 | |
| 213 | === 4.4 Define parameters for Graph === |
| 214 | |
| 215 | Line Graph |
| 216 | |
| 217 | {{{ |
| 218 | |
| 219 | defGraph 'SSID' do |g| |
| 220 | g.ms('wrapper_wimaxss').select(:oml_ts_client, :ssid, :ifacemac) |
| 221 | g.caption "SSID" |
| 222 | g.type 'line_chart3' |
| 223 | g.mapping :x_axis => :oml_ts_client, :y_axis => :ssid, :group_by => :ifacemac |
| 224 | g.xaxis :legend => 'unix_ts' |
| 225 | g.yaxis :legend => 'SSID', :ticks => {:format => 's'} |
| 226 | end |
| 227 | |
| 228 | |
| 229 | }}} |
| 230 | |
| 231 | |
| 232 | HistoGram |
| 233 | {{{ |
| 234 | defGraph 'SSID' do |g| |
| 235 | g.ms('wrapper_wimaxss').select(:oml_ts_client, :ssid, :netoper) |
| 236 | g.caption "SSID of Carriers" |
| 237 | g.type 'histogram2' |
| 238 | g.mapping :value => :ssid, :group_by => :netoper |
| 239 | g.xaxis :legend => 'Unix TS' |
| 240 | g.yaxis :legend => 'SSID' |
| 241 | end |
| 242 | }}} |
| 243 | |
| 244 | |
| 245 | === 4.5 Full Script is given below === |
| 246 | |
| 247 | {{{ |
| 248 | defProperty('source1', "nodec-gimidev1", "ID of a resource") |
| 249 | defProperty('intervalcol',"1", "Interval to Tail") |
| 250 | |
| 251 | defProperty('pathfile', "/root/wimaxtest.txt", "Path to file") |
| 252 | |
| 253 | |
| 254 | |
| 255 | defApplication('ofstats') do |app| |
| 256 | app.description = 'Simple Definition for the of-collect application' |
| 257 | # Define the path to the binary executable for this application |
| 258 | app.binary_path = '/usr/local/bin/ofcollect.rb' |
| 259 | app.defProperty('target', 'Address to output file', '-f', {:type => :string}) |
| 260 | app.defProperty("interval","Interval",'-i', {:type => :string}) |
| 261 | app.defMeasurement('wrapper_wimaxss') do |m| |
| 262 | m.defMetric(':pathtype', :string) |
| 263 | m.defMetric('throughput',:int64) |
| 264 | m.defMetric('instput',:int64) |
| 265 | end |
| 266 | end |
| 267 | defGroup('Source1', property.source1) do |node| |
| 268 | node.addApplication("ofstats") do |app| |
| 269 | app.setProperty('target', property.pathfile) |
| 270 | app.setProperty('interval', property.intervalcol) |
| 271 | app.measure('wrapper_wimaxss', :samples => 1) |
| 272 | end |
| 273 | end |
| 274 | |
| 275 | |
| 276 | onEvent(:ALL_UP_AND_INSTALLED) do |event| |
| 277 | info "Starting the collect" |
| 278 | after 2 do |
| 279 | group('Source1').startApplications |
| 280 | end |
| 281 | after 800 do |
| 282 | info "Stopping the collect" |
| 283 | allGroups.stopApplications |
| 284 | Experiment.done |
| 285 | end |
| 286 | end |
| 287 | |
| 288 | defGraph 'SSID' do |g| |
| 289 | g.ms('wrapper_wimaxss').select(:oml_ts_client, :ssid, :ifacemac) |
| 290 | g.caption "SSID" |
| 291 | g.type 'line_chart3' |
| 292 | g.mapping :x_axis => :oml_ts_client, :y_axis => :ssid, :group_by => :ifacemac |
| 293 | g.xaxis :legend => 'unix_ts' |
| 294 | g.yaxis :legend => 'SSID', :ticks => {:format => 's'} |
| 295 | end |
| 296 | defGraph 'SSID' do |g| |
| 297 | g.ms('wrapper_wimaxss').select(:oml_ts_client, :ssid, :netoper) |
| 298 | g.caption "SSID of Carriers" |
| 299 | g.type 'histogram2' |
| 300 | g.mapping :value => :ssid, :group_by => :netoper |
| 301 | g.xaxis :legend => 'Unix TS' |
| 302 | g.yaxis :legend => 'SSID' |
| 303 | end |
| 304 | |
| 305 | }}} |