Help with custom data query XML script

Post general support questions here that do not specifically fall into the Linux or Windows categories.

Moderators: Developers, Moderators

Post Reply
skatter
Cacti User
Posts: 153
Joined: Fri Oct 22, 2004 2:55 am
Contact:

Help with custom data query XML script

Post by skatter »

I'm trying to create an SNMP indexed data query, and I'm having trouble with one of the OIDs that needs to be walked. To summarize, I am trying to index: slot #, slot description, and the 60 second interval for CPU utilization (there are 1, 5, 60, and 300 second intervals available).

The slot # and slot descriptions values are populating without an issue, but I run into a problem once the CPU load intervals are indexed, as each slot # returns 4 values (one for each load interval), like so:

Code: Select all

Slot #1:
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.1.1.1 = INTEGER: 1
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.1.1.5 = INTEGER: 5
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.1.1.60 = INTEGER: 60
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.1.1.300 = INTEGER: 300

Slot #2:
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.2.1.1 = INTEGER: 1
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.2.1.5 = INTEGER: 5
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.2.1.60 = INTEGER: 60
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.2.1.300 = INTEGER: 300

Slot #3:
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.3.1.1 = INTEGER: 1
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.3.1.5 = INTEGER: 5
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.3.1.60 = INTEGER: 60
.1.3.6.1.4.1.1991.1.1.2.11.1.1.3.3.1.300 = INTEGER: 300
Here is what it looks like in the graph creation menu (you'll notice that the intervals seem to get spread out randomly):
Data Query Output.png
Data Query Output.png (67.34 KiB) Viewed 1056 times
My goal is to only gather the value for the 60 second interval, and ignore the 1, 5, and 300 second intervals, but that's proving to be more difficult than I had anticipated. Is there a way to parse out just the OID ending in 1.60? I've also attached my XML file.
Attachments
brocade_mlxe_cpu.xml
(1.43 KiB) Downloaded 111 times
skatter
Aralhach
Posts: 10
Joined: Tue May 28, 2013 10:46 pm

Re: Help with custom data query XML script

Post by Aralhach »

I've seen some people with a similar problem. In my experience, SNMP Data Queries still lack a lot of flexibility, power, and reliability. I'd recommend putting a small script together (I used BASH, and the normal "snmpbulkwalk" command available - you can use the PHP libraries provided by Cacti as well, but I wanted to use bash). With bash, you can "grep" out the OIDs you don't want, when pulling the OIDs out. "grep" is a command that allows filtering of certain lines, that match a certain filter (you'd use REGEXP/Regular Expressions for what you'd want - you'd even need them to parse the Index in the SNMP Data Query, so I'd much rather using a script... you have A LOT more control of what's being output, and it's easier to debug too :D).

A walkthrough to use Data Queries is at:
http://docs.cacti.net/manual:087:3a_adv ... alkthrough
However, this guide uses PHP. I like the elegance of Bash, and the fact that it's just command line stuff that can be easily run and tested.
If you want some help with Bash, or anything else, I'll be glad to oblige.
skatter
Cacti User
Posts: 153
Joined: Fri Oct 22, 2004 2:55 am
Contact:

Re: Help with custom data query XML script

Post by skatter »

Can you post one of the bash scripts you've already created?
skatter
Aralhach
Posts: 10
Joined: Tue May 28, 2013 10:46 pm

Re: Help with custom data query XML script

Post by Aralhach »

OK! I made these scripts for a couple Redback SmartEdge SE400 machines.

#1: Subscribers per Context (SE400 manages the Quality of Service for different subscribers, so this basically keeps track of how many subscribers are online in every context - a context can be a certain bandwidth plan, for instance).
It's a wee bit... raw, and I didn't add any "usage" prompts, as I intended only Cacti to run it. I could put them in though, and I might do it later. :) In the XML file, I used the <arg_prepend>|host_hostname| |host_snmp_community| |host_snmp_port| |host_max_oids|</arg_prepend> option, to have those values sent to the script before the "get" or "index" option that Cacti uses to poll data. (hence the $1 $2 $3 $4 usage in the script).
The 5th argument is "numconts" (specified like that in the XML file), or index, query, etc. The documentation said that it would go "script query <field>", but it actually did "script <field>" directly, so I added both options just in case. (This problem ended up being a missing field in the XML file: <arg_query>, which is now added) I used grep to filter out one context that came out blank ("") and had no corresponding subscriber number, so everything would match. I just used the numbers 1-9 or whatever, as the index. I used awk to print the line number before the line (to simulate the index, and also for filtering the requested value). I used snmpbulkwalk, as it helps reduce network overhead, packing more SNMP requests into one IP packet. You can change it to snmpwalk if you'd like, removing the 4th parameter from the arg_prepend and changing the argument numbers in the script.

Code: Select all

case "$5" in
	numconts) /usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.6.3.16.1.1.1.1 | grep -v \"\" | wc -l ;; # count number of values in the SNMPWALK
	index) seq `/usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.6.3.16.1.1.1.1 | grep -v \"\" | wc -l` ;;
	query)
		if [ $6 = "context" ]
		then
			/usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.6.3.16.1.1.1.1 | grep -v \"\" | cut -d "\"" -f 2 | awk '{print NR ":" $0}'
		elif [ $6 = "subs" ]
		then
			/usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.4.1.2352.2.27.1.2.1.1.1 | cut -d ":" -f 2 | awk '{print NR ":" $1}'
		fi
	;;
	get)
		if [ $6 = "context" ]
		then
			/usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.6.3.16.1.1.1.1 | grep -v \"\" | cut -d "\"" -f 2 | awk '{print NR ":" $0}' | grep $7: | cut -d ":" -f 2
		elif [ $6 = "subs" ]
		then
			/usr/bin/snmpbulkwalk -Cr$4 -v 2c -c $2 $1:$3 .1.3.6.1.4.1.2352.2.27.1.2.1.1.1 | cut -d ":" -f 2 | awk '{print NR ":" $1}' | grep $7: | cut -d ":" -f 2
		fi
	;;
	*) exit 1 ;;
esac
By the way, the $0 or $1 inside the AWK command, are NOT the command line arguments, but fields split by AWK from the input. Bash does not replace the command line arguments $0, $1, if they are inside apostrophes ('$0' will literally print $0, but "$0" will print the script name, anywhere in a Bash script).

The XML file looks like this:

Code: Select all

<query>
	<name>SmartEdge - Subscribers per context</name>
	<description>Monitors # of subscribers in each service context</description>
	<script_path>/bin/bash |path_cacti|/scripts/SE400subs.sh</script_path>
	<arg_prepend>|host_hostname| |host_snmp_community| |host_snmp_port| |host_max_oids|</arg_prepend>
	<arg_index>index</arg_index>
	<arg_query>query</arg_query>
	<arg_get>get</arg_get>
	<arg_num_indexes>numconts</arg_num_indexes>
	<output_delimeter>:</output_delimeter>
	<index_order_type>numeric</index_order_type>
	<index_title_format>|context|</index_title_format>
	<fields>
		<context>
			<name>Context</name>
			<direction>input</direction>
			<query_name>context</query_name>
		</context>
		<subs>
			<name>Subscribers</name>
			<direction>output</direction>
			<query_name>subs</query_name>
		</subs>
	</fields>
</query>
I don't REALLY understand why a couple of things are necessary (like the index_title_format), but it works. The query_name is the string Cacti will pass as the argument to get an index of the field.

I was thinking of posting some more scripts and XML files (I have a couple more; in the other one I used "sed" instead of awk and cut, since the index was part of the OID - an IP address, not just a number). If you'd like me to post those, I can... just didn't want to make this post too long :)
Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests