In this example, we look at adding an SDK transformation script to lookup IP addresses and TCP ports and mapping those onto a customer name.

The mapping config file will be a separate file to the SDK script, so that it can be generated programmatically if needed.

We will use a latency probe as an example, and generate a new datafield which is then populated into a tag.

The tag can then be used inside the associated latency analyser configuration to aggregate stats based on customer, or to store in the latency feed DB.

The probe should have SDK transformation enabled.

The Script File parameter should be the full path to the js file - /data/sdk/customer_mapping/customer_mapping.js

Save the following code into /data/sdk/customer_mapping/customer_mapping.js

mkdir -p /data/sdk/customer_mapping if it doesn't exist

var console = vu8.load('console')
vu8.run('/data/sdk/customer_mapping/customers.js')
function new_dec_helper(dec, name) {
dec.log = function(msg) {
console.log(name + ' decoder :', msg)
}
}
// fields to lookup from the decoded content
var df_src_host = decoder.protocol.getDatafield("ip.src_host")
var df_dst_port = decoder.protocol.getDatafield("ip.dst_port")
// fields to set for use by probes
var df_customer = new decoder.DatafieldString("sdk.customer")
var df_hostname = new decoder.DatafieldString("sdk.hostname")
try {
// Register datafields with decoder's protocol layer.
decoder.protocol.addDatafield(df_customer)
decoder.protocol.addDatafield(df_hostname)
}
catch (e) {
console.log('sdk decoder: error adding data fields')
}
console.log('sdk decoder: loaded script')
function on_new_decoder(dec) {
new_dec_helper(dec, 'customer_mapping')
//dec.log('new')
}
function on_data(dec) {
try {
//dec.log("on data")
var dst_port_str = ''+df_dst_port.get()
var src_ip_str = ''+df_src_host.get()
try {
// lookup the hostname from the ip map - item 0 in the array
df_hostname.set(customerMap[src_ip_str][0])
// lookup the customer name from the ip map
// - item 1 in the aray is the list of port number to names
df_customer.set(customerMap[src_ip_str][1][dst_port_str])
} catch (e) {
// exceptions will be thrown if the lookup fails
//console.log('script decoder: exception mapping IP fields')
//console.log(e)
}
} catch (e) {
//console.log('script decoder: exception getting data fields')
//console.log(e)
}
dec.nextDecoder()
}
function on_missed_data(dec, size) {
// never mind, just report it for now
dec.log("sdk missed data of length: " + size.toDouble())
dec.buffer.reset()
}

Now save the following code into

/data/sdk/customer_mapping/customers.js


var customerMap = {
"10.10.1.1": [ "hosta", { "1001": "Customer X", "1002": "Customer Y" } ],
"10.10.1.2": [ "hostb", { "1001": "Customer Z" } ],
"10.10.1.3": [ "hostc", { "1003": "Customer Z" } ]
}

This map is in JSON format.


It has a primary lookup index of IP address - in our case we care about the src IP of customers .

For each IP, we then have a hostname, and then a list of port number to customer name maps.

The port number in this case is the destination port of customer requests - ie the server port.

This is just an example but can lend itself to lookup tables for FIX CompIDs, message types etc.

Now - in the latency probe configuration - you can add tags to store these 2 new datafields - sdk.customer and sdk.hostname.

You must add them manually, the gui drag and drop wizard does not yet support sdk datafields.

e.g.

{sdk.customer}