After starting out with LUA and struggling with tables and getting my data out of them and thanks to various people on this forum I have started to get my head around how they work. I wrote this short article in effort to share this beginner knowladge with others like myself.
This will also be in the Nimsoft KB but posting here also as this seems to be the "place" for development chatter.
There are probably many better ways to achieve similar results but if, like myself your struggling to get your head round tables this might help get you started
-------------------------------
In this article we will take a closer look at LUA tables. Most of the data we return from callbacks will be stored in LUA tables hence we need a strong understanding of table structure and how to access the data contained within.
First we build a basic script to return the values from the “getrobots” call back from a hub and store this data in a table. For a more in depth look at building call back requests with the nimbus.request function see other articles in this LUA series.
--Connect to hub probe. Edit this line with the address of your hub you wish to query local addr = "/nevil-nmsdom/nevil-nmshub/nevil-nms/hub" --Command to request configuration of probe local command = "getrobots" --Build PDS answer file when probe_config_get asks for probe name local args = pds.create() pds.putString(args, "name", "", "detail", "") --Send request and store data in h_resp{} local h_resp,rc = nimbus.request(addr, command, args) print(h_resp)
Execute this in the NAS script editor and it will produce out similar to the below:
----------- Executing script at 07/08/2012 15:07:06 ----------
table:0x2275b50
In order for us to extract anything valuable from the said table we need to understand the table structure. At this point I refer you to the “LUA- tdumper” article. If you have not yet followed this article I highly suggest you do as the rest of this article will be much easier to follow. So assuming we have the tdumper.lua file saved in the nas/scripts/ folder at the top of our script we can use:
dofile "scripts/tdumper.lua"
to include this function in our above code and replace the print function with:
tdump(h_resp)
Executing the script now produces a full list of the table. A snippet is shown below for reference:
----------- Executing script at 07/08/2012 15:14:07 ---------- root: domain:nevil-nmsdom robotlist: 1: ssl_mode:0 os_user2: origin:nevil-nmshub os_major:UNIX ip:192.168.1.58 os_minor:Linux addr:/nevil-nmsdom/nevil-nmshub/nevil-multibot_03 status:0 license:1 last_inst_change:1340754931 created:1341306789 offline:0 last_change:1341306869 lastupdate:1344348377 autoremove:0 os_user1: flags:1 os_description:Linux 2.6.32-5-amd64 #1 SMP Mon Jan 16 16:22:28 UTC 2012 x86_64 name:nevil-multibot_03 metric_id:M64FB142FE77606C2E924DD91FFCC3BB4 device_idDFF83AB8CD8BC99B88221524F9320D22 heartbeat:900 port:48100 version:5.52 Dec 29 2011
Addressing Table Elements
Now we can preview the table structure we can start selecting table elements. The output you see from this request is called a “nested table” which is essentially tables stored within tables and can get quite messy for the beginner to get their head around. Programmers with a background in Perl for example will have a distinct advantage when tackling LUA tables.
So what do we have here? Let’s break this table up a little, to keep things simple lets list the main elements of the table. Start by commenting out our tdump function:
--tdump(h_resp)
Add the following:
for k,v in pairs(h_resp) do print(k.." ",v) end
This simple code says for each table entry in the h_resp table print its key (k) and value (v) pairs. The table h_resp we created has two initial entries domain and robotlist:
domain nevil-nmsdom robotlist table:0x22a0a60
From this return we can see the key for “domain” has a string value of “nevil-nmsdom” the name of my hub robot. The robotlist key is slightly more complicated as its “value” is actually another table, a “nested” table. To list the entries from the “robotlist” key we can just append the key name to the table name.
for k,v in pairs(h_resp.robotlist) do print(k.." ",v) end
This provides us with yet another list of tables, one for each of the robots the call back found:
1 table:0x2213600 0 table:0x2392ab0 3 table:0x2394c30 2 table:0x225eb80 5 table:0x22133e0 4 table:0x22131f0 7 table:0x2275b00 6 table:0x227d6f0 8 table:0x227d490
We can drill down further and examine one of these tables with:
for k,v in pairs(h_resp.robotlist["1"]) do print(k.." ",v) end
We can provide any of the integer values of the “key” to examine that particular table in this case we used “1”
ssl_mode 0 os_user2 origin nevil-nmshub os_major UNIX ip 192.168.1.58 os_minor Linux addr /nevil-nmsdom/nevil-nmshub/nevil-multibot_03 status 0 license 1 last_inst_change 1340754931 created 1341306789 offline 0 last_change 1341306869 lastupdate 1344590476 autoremove 0 os_user1 flags 1 os_description Linux 2.6.32-5-amd64 #1 SMP Mon Jan 16 16:22:28 UTC 2012 x86_64 name nevil-multibot_03 metric_id M64FB142FE77606C2E924DD91FFCC3BB4 device_id DDFF83AB8CD8BC99B88221524F9320D22 heartbeat 900 port 48100 version 5.52 Dec 29 2011
Now all that probably seemed like a lot of work but by now we should be getting used to how to address tables and start getting at the data we want.
Now let’s assume we are just interested in the “name” key. We can print the value for they “name” key of this table with the following syntax:
print(h_resp.robotlist["1"].name) ----------- Executing script at 10/08/2012 11:56:57 ---------- nevil-multibot_04
If we wanted to return all the name values for each of the tables stored under “robotlist”:
for k,v in pairs (h_resp.robotlist) do print(v.name) end ----------- Executing script at 10/08/2012 13:41:30 ---------- nevil-multibot_03 nevil-mysql nevil-multibot_02 nevil-multibot_04 debian-apache nevil-ump nevil-nms nevil-windows-dc1 Nevil-MS-SQL
As we discussed we can iterate through an entire table and its nested tables using the tdump function. However from time to time you might just require to iterate over a single nested table. To help us understand which table to iterate over for a particular robot edit our previous syntax to display the “key” the robot “Name” value descended from.
for k,v in pairs (h_resp.robotlist) do print(k," "..v.name) end ----------- Executing script at 10/08/2012 13:51:49 ---------- 1 nevil-multibot_03 0 nevil-mysql 3 nevil-multibot_02 2 nevil-multibot_04 5 debian-apache 4 nevil-ump 7 nevil-nms 6 nevil-windows-dc1 8 Nevil-MS-SQL
Now we can see what table index within h_resp.robotlist belongs to which robot. As an example iterating over h_resp.robotlist[“1”] would give us the information about nevil-multibot_03, we have already written the code for this in a previous example as an exercise I will leave you to explore this.
As a final note in the article let’s look at how we would iterate over the whole of h_resp.robotlist and just this nested table. This becomes a little more technical as we need to create a new function.
function DeepPrint(a) if type(a) == "table" then for k,v in pairs(a) do print(k.." ",v) DeepPrint(v) end else end end
I won’t go into any great depth here but if the script sees that a values nests another table it will iterate over that too.
Execute this function passing it the name of the table we want to iterate over:
DeepPrint(h_resp.robotlist) ----------- Executing script at 10/08/2012 13:59:17 ---------- 1 table:0x2394df0 ssl_mode 0 os_user2 origin nevil-nmshub os_major UNIX ip 192.168.1.58 os_minor Linux addr /nevil-nmsdom/nevil-nmshub/nevil-multibot_03 status 0 license 1 last_inst_change 1340754931 created 1341306789 offline 0 last_change 1341306869 lastupdate 1344603075 autoremove 0 os_user1 flags 1 os_description Linux 2.6.32-5-amd64 #1 SMP Mon Jan 16 16:22:28 UTC 2012 x86_64 name nevil-multibot_03 metric_id M64FB142FE77606C2E924DD91FFCC3BB4 device_id DDFF83AB8CD8BC99B88221524F9320D22 heartbeat 900 port 48100 version 5.52 Dec 29 2011 0 table:0x22135b0 ssl_mode 0 os_user2 origin network os_major UNIX ip 192.168.1.31 os_minor Linux addr /nevil-nmsdom/nevil-nmshub/nevil-mysql status 0 license 1 last_inst_change 1342178648 created 1341922451 offline 0 last_change 1344591508 lastupdate 1344603108 autoremove 0 os_user1 flags 1 os_description Linux 2.6.32-5-amd64 #1 SMP Mon Jan 16 16:22:28 UTC 2012 x86_64 name nevil-mysql metric_id M7CDEF667D86384966EF5876BEAB7AA52 device_id D518C83671EA63842F7C08EEBA7DD63E2 heartbeat 900 port 48000 version 5.63 Mar 2 2012