One area where Nagios is severely lacking is bandwidth utilization monitoring of network devices. Since I already have a fully-functioning Cacti server and a scaled up Nagios server, I wrote my own python plugin to do the job.
Overview
Here’s what the check_port_sturation.py plugin does:
- Make SNMP call to determine max speed of an interface
- Open specified interface graph via https and download the associated CSV data file.
- Compute the 5-minute average Inbound and Outbound bandwidth utilization
- Check these values against specified thresholds (given in percentages)
- Enter warning or critical state when utilization exceeds thresholds
Let’s begin.
Map ifIndex to Cacti Graph ID
Cacti Device and Graph ID’s are arbitrary so you will need to map them to your devices’ hostname and interface ifIndex values, respectively.
Luckily it’s pretty easy to do this regardless of how many devices and interfaces you are monitoring.
1. Ensure You Are Using Consistent Naming Schemes in Cacti and Nagios
If your Nagios checks are using “dist1”, then use “dist1” for the Hostname and Description fields in Cacti. This will make the mapping and scripting steps easier.
2. Update Cacti Graph Description with SNMP ifIndex
Cacti is already polling your device, so why not use it to get all the information we need?
Find the graph template you are using for interface traffic monitoring (I suggest first following my post on Dressing up Cacti graphs) and update the graph title field as follows:
|host_description| |query_ifIndex| |query_ifName| |query_ifAlias|
Variable descriptions:
host_description: The field covered in Step 1
query_ifIndex: This is the SNMP index of the interface.
query_ifName: The SNMP name of the physical interface (Not required)
query_ifAlias: The description you set for your interface in IOS. (Not required)
Screen shot example:
Your graphs will now look like this:
3. Use Built-In Cacti Scripts to Get Device and Graph IDs
(Note: Detailed instructions for Cacti built-in scripts are located here – http://www.cacti.net/downloads/docs/html/scripts.html)
First we want to get a list of our devices and their Cacti device ID’s. This is done by using the following built-in Cacti script:
php /usr/share/cacti/cli/add_graphs.php --list-hosts
Output will be as follows:
porter@cacti:~$ php /usr/share/cacti/cli/add_graphs.php --list-hosts Known Hosts: (id, hostname, template, description) 5 core1 5 core1 141 dist1 13 dist1 143 dist2 13 dist2 183 sw-r07-03a 12 sw-r07-03a 184 sw-r07-03c 12 sw-r07-03c 185 sw-r07-04a 12 sw-r07-04a
With this information we can get a list of the Graph ID’s associated with each host.
php /usr/share/cacti/cli/add_tree.php --list-graphs --host-id=141
Since we updated the Graph Descriptions earlier, this output now contains all the information we need for our check:
porter@cacti:~$ porter@cacti:~$ php /usr/share/cacti/cli/add_tree.php --list-graphs --host-id=141 Known Host Graphs: (id, name, template) 7318 dist1 437841920 Ethernet4/16 NEXUS2: E4/16 [Po4096] 3: Interface - Traffic (bits/sec) 7319 dist1 437317632 Ethernet3/16 NEXUS2: E3/16 [Po4096] 3: Interface - Traffic (bits/sec) 7322 dist1 369098752 port-channel1 [eth1/1] sw-r03-08a: te0/1 3: Interface - Traffic (bits/sec) 7323 dist1 369098753 port-channel2 [eth1/2] sw-r07-03a: te1/1 3: Interface - Traffic (bits/sec) 7324 dist1 369098754 port-channel3 [eth1/3] sw-r07-03c: te1/1 3: Interface - Traffic (bits/sec) 7325 dist1 369098755 port-channel4 [eth1/4] sw-r07-04a: te1/1 3: Interface - Traffic (bits/sec)
To do both tasks in one step, you can use the following Bash script:
#!/bin/bash for device in `php /usr/share/cacti/cli/add_graphs.php --list-hosts | awk '{print $1}'`; do php /usr/share/cacti/cli/add_tree.php --list-graphs --host-id=$device \ | grep Traffic | awk '{print $2";"$4";"$1";"$3}'; \ done
(Note: The “grep Traffic” portion is filtering out other graph templates)
This will cycle through all of your cacti devices and provide you with a nice semi-colon separated file output in the following format:
hostname;interface_name;graph_id;ifIndex
Example:
dist1;port-channel1;7322;369098752 dist1;port-channel2;7323;369098753 dist1;port-channel3;7324;369098754 dist1;port-channel4;7325;369098755 dist1;port-channel5;7326;369098756
Run this script and save your output to a text file that can then be copied over to your Nagios server:
porter@cacti:~$ get_cacti_data.sh >> cacti_graph_mappings
Installation
You’ll need to have Python 2.7 and the specified modules installed on your Nagios server in order to use this plugin. You will also need to update all paths to suit your environment.
1. Download Plugin
The latest revision of this plugin can be downloaded from the Nagios Exchange:
#!/opt/python/bin/python2.7 # Paul Porter 2013 http://paulgporter.net import csv import cStringIO import datetime import netsnmp import requests import argparse import sys # Listing of arguments this command will accept. Defaults are given for some values. def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser(description='nagios port saturation check') parser.add_argument('-H', '--host', required=True, help='Host we are checking') parser.add_argument('-C', '--snmp_com', default='public', required=True, help='SNMP community') parser.add_argument('-V', '--snmp_ver', type=int, default=2, choices=[1, 2, 3], help='SNMP version') parser.add_argument('-g', '--graph_id', required=True, help='Cacti graph id') parser.add_argument('-s', '--cacti_server', required=True, help='Cacti server hostname') parser.add_argument('-c', '--crit', default=90, type=int, help='critical saturation level in %') parser.add_argument('-w', '--warn', default=80, type=int, help='warning saturation level in %') parser.add_argument('-i', '--if_index', required=True, help='ifIndex value for snmp') args = parser.parse_args(argv) # Create empty arrays inbound = [] outbound = [] # Download the data from Cacti. Update the cert path to match yours. text = requests.get('https://'+ args.cacti_server +'/cacti/graph_xport.php?local_graph_id='+ args.graph_id +'&rra_id=5&view_type=', verify='/etc/ssl/certs/ca-certificates.crt').content # If download was successful parse the CSV file, skip the headers, and retrieve data from the Inbound and Outbound columns. Otherwise exit with an error. if len(text) > 1 : for i in csv.DictReader(cStringIO.StringIO(text[text.index('""') + 3:])): if datetime.datetime.now() - datetime.datetime.strptime(i['Date'], '%Y-%m-%d %H:%M:%S') <= datetime.timedelta(minutes=17): inbound.append(float(i['Inbound']) / (100 * 1024 * 1024) * 100), outbound.append(float(i['Outbound']) / (100 * 1024 * 1024) * 100), else : print "ERROR: No Results Found" sys.exit(text) # Use SNMP with the provided Hostname and IfIndex values to get the maximum speed of this interface max_speed = (netsnmp.snmpget(netsnmp.Varbind('.1.3.6.1.2.1.31.1.1.1.15.' + args.if_index), DestHost=args.host, Version=args.snmp_ver, Community=args.snmp_com, UseNumeric=True)[0]) # Takes the data from the Inbound and Outbound columns, converts it to Mbps, and adds to the arrays avg_inbound = round(sum(inbound) / len(inbound), 2) avg_outbound = round(sum(outbound) / len(outbound), 2) # Apply the specified WARN and CRIT levels to the max speed and convert to decimal format warn_threshold = int(max_speed) * (args.warn * .01) crit_threshold = int(max_speed) * (args.crit * .01) # Compare values if (avg_inbound >= crit_threshold) or (avg_outbound >= crit_threshold) : print 'CRITICAL: Avg_In= %s Mbps and Avg_Out= %s Mbps' % (avg_inbound, avg_outbound) elif (warn_threshold <= avg_inbound) or (warn_threshold <= avg_outbound) : print 'WARNING: Avg_In= %s Mbps and Avg_Out= %s Mbps' % (avg_inbound, avg_outbound) elif (0 <= avg_inbound <= warn_threshold) and (0 <= avg_outbound <= warn_threshold): print 'SUCCESS: Avg_In= %s Mbps and Avg_Out= %s Mbps' % (avg_inbound, avg_outbound) if __name__ == '__main__': main()
2. Add to Nagios commands.cfg
The command usage is as follows:
usage: check_port_saturation.py [-h] -H HOST -g GRAPH_ID [-s CACTI_SERVER] [-c CRIT] [-w WARN] [-V {1,2,3}] [-C SNMP_COM] -i IF_INDEX
When you add the command to Nagios, you can pass those options as either values or arguments. Run it a few times from the command line to make sure that it is working properly.
Here is an example which uses defaults for -c,-w,-V, -s, and -C.:
define command { command_name check_port_saturation command_line /etc/nagios3/plugins/check_port_saturation.py -H $HOSTADDRESS$ -g $ARG1$ -i $ARG2$ }
3. Add to Nagios services.cfg
With the cacti_graph_mappings file we created earlier, it’s easy to feed that to a script to generate the Nagios services configuration for you. If you’re unsure of how to do this, you can run the following example from a command line or bash script to get a basic configuration built.
This command is feeding awk the cacti_graph_mappings file and appending the output to our existing services.cfg file.
awk -F';' '{print "\ define service { \n \ use \t generic-network-service-template \n \ hosts \t "$1" \n \ service_description \t"$2"_Usage \n \ check_command \t check_port_saturation!"$3"!"$4" \n \ } \n"}' cacti_graph_mappings >> /etc/nagios3/conf.d-constant/services.cfg
Output will look as follows:
define service { use generic-network-service-template hosts dist4 service_description Ethernet1/45_Usage check_command check_port_saturation!23715!436387840 } define service { use generic-network-service-template hosts dist4 service_description Ethernet1/46_Usage check_command check_port_saturation!23716!436391936 }
4. Restart Nagios
You should now see results like this in Nagios:
Finished!
Additional Enhancements
Here are a few other useful ideas for implementing this plugin in your environment…
One Page Viewing of Bandwidth Usage
Cacti has a 100-graphs-per-page viewing limit, which means you’ll have to do some clicking around if you want to get a complete overview of bandwidth usage in your network. By creating a Nagios Service Group for the plug-in we just wrote it’s possible to get a complete listing of bandwidth usage on ALL monitored interfaces on one page.
Here’s an example of how it would look:
2. Add Links to the Cacti Graph
Another cool thing you can do is add a link to the associated Cacti graph as a Service Comment.
(Note: Detailed instructions for the nagios.cmd command can be found here – http://nagios.sourceforge.net/docs/3_0/extcommands.html)
So. let’s do this on the bandwidth check for interface Ethernet1/10 on Dist1. To add the comment we would run the following command.
printf "[%lu] ADD_SVC_COMMENT;dist1;Ethernet1/10_Usage;1;PORTER;<a href="https://netprobe/cacti/graph.php?action=view\&rra_id=all\&local_graph_id=7378">https://netprobe/cacti/graph.php?action=view&rra_id=all&local_graph_id=7378</a>\n" `date +%s` > /var/lib/nagios3/rw/nagios.cmd
Important: You must use a backslash before the ampersand symbol in the anchor tag otherwise the command will not work correctly.
You will now see a comment icon next to the service description as shown below.
Clicking the comment will open the service description and you will now see a URL at the bottom of the page
Clicking on that link will show you the Cacti graph.
This can easily be scripted for all interfaces using the files we created earlier in this post.
Hello! Have you script without SSL verify.
Open the check_port_saturation.py script with a text editor and change this line:
text = requests.get(‘https://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’, verify=’/etc/ssl/certs/ca-certificates.crt’).content
To this:
text = requests.get(‘http://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’
When I run the script I am getting an error File “./check_port_saturation.py”, line 45, in main
if len(text) > 1 :
TypeError: object of type ‘Response’ has no len()
Nvm I figured out my mistake. I forgot to add ‘.content’ to the end of the previous comment. If you change from https to http the final change should look like
text = requests.get(‘http://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’).content
Cool, thanks David
When i try too run the first service check I get: (Return code of 126 is out of bounds – plugin may not be executable)
Hey Adam,
Verify that the plugin is executable (chmod +x).
Thanks for the swift response Paul. Will give it a try. Oh and thanks for the excellent documentation on a most excellent plug in 🙂
You’re welcome! I hope it proves to be as useful for you as it has been for me.
Hello again,
When i try too run the first service check I get: (Return code of 126 is out of bounds – plugin may not be executable)
I am using snmp v3 which doesn’t use a community though when running the check manually on the command line I get the following out put.
# ./check_port_saturation.py -H 192.168.0.5 -v 3 -u snmpusername -p ‘password’ -i 5
-bash: ./check_port_saturation.py: /opt/python/bin/python2.7: bad interpreter: No such file or directory
Nagios is reporting: “Return code of 127 is out of bounds – plugin may be missing” which suggests to me it may be an issue with the SNMP. Have I got the syntax right?
Thanks again.
Adam
Hey Adam,
The problem is that you are using SNMPv3 and the current plugin doesn’t ask for credentials or use them when it collects max speed:
max_speed = (netsnmp.snmpget(netsnmp.Varbind(‘.1.3.6.1.2.1.31.1.1.1.15.’ + args.if_index), DestHost=args.host, Version=args.snmp_ver, Community=args.snmp_com, UseNumeric=True)[0])
I will have to re-write the plug-in to support it. I’ll send you a version to test with by the end of next week.
Thanks, I appreciate that.
Hi Paul, I was wondering how you are progressing with the SNMPv3 plugin. I have had an attempt but my skills in Python are beyond basic 😉
Apologies – it is not seeing the interpreter. I need to pre-append python to get a little further. Still struggling with the syntax though.
Now. I have tried with your guide but when I run the script I am getting an error File “./check_port_saturation.py”, line 45, in main
if len(text) > 1 :
I hope your help.
Thank so much!
I use Ubuntu Server and i modify with:
#!/opt/python/bin/python2.7
to this:
#!/usr/bin/python2.7
after was error:
root@nagios:/usr/local/nagios/libexec# ./check_port_saturation.py
File “./check_port_saturation.py”, line 45
if length(text) > 1 :
^
IndentationError: unexpected indent
HOPE with your help!
Thanks
Hello,
Python is very picky about the use of formatting and is unhappy with your file.
Did you modify the file by doing a copy and paste from a different text editor? If so, it can introduce additional formatting that isn’t noticeable at first.
If you did a copy paste, try downloading the file again and using vim to edit the file instead. This way you don’t have to worry about extra spaces from a copy and paste.
Hello Paul.
I’m checked from command line and I got this error:
/usr/local/nagios/libexec/check_port_saturation.py -H next01-cisco-dl-sw1 -C public -s “cacti-server-host” -g 45 -i 10148
Traceback (most recent call last):
File “/usr/local/nagios/libexec/check_port_saturation.py”, line 77, in
main()
File “/usr/local/nagios/libexec/check_port_saturation.py”, line 47, in main
if datetime.datetime.now() – datetime.datetime.strptime(i[‘Date’], ‘%Y-%m-%d %H:%M:%S’) <= datetime.timedelta(minutes=17):
KeyError: 'Date'
Can you help me?
Thanks.
# If download was successful parse the CSV file, skip the headers, and retrieve data from the Inbound and Outbound columns. Otherwise exit with an error.
print “—>%s<—" % (text)
# 2014-10-14: To review the result information
i had typed wrong “comment” -> uncomment. Sorry
sure, no problem!
Really usefull plugin. Combining Cacti and Nagios in this was is very useful to me.
However, I’m looking to go a step further. I would like to pull Network traffic bandwidth usage data from Cacti into Nagios to feed Nagvis weathermap lines in an attempt to have the best of Nagvis and Cacti weathermap combined as well.
This plugin seems to be most of the way there but I need it to produce perfData in the required format.
“example: inUsage=21103.42%;85;98 outUsage=226363.55%;85;98 inBandwidth=105.52MBs outBandwidth=212.22MBs”
http://docs.nagvis.org/1.7/en_US/lines_weathermap_style.html
I’ll attempt to modify your plugin and let you know how I get on!
Hi I have now successfully modified your code to present performance data that will drive the Nagvis weathermap feature.
Let me know if you would likle a copy of my code.
Thanks!
Rob
Yes, please share it if possible. Thank you
Can this plugin help if i want the total bandwith usage for a month in volume (ie 20Go ) ?
HI, when I run the command to try to pull all the graphs, Id’s and indexes, it comes out as 13;â . Not sure why i’m getting that weird character. Any ideas?
If you copied and pasted that script try typing it out in a terminal window instead. Perhaps some RTF encoding got carried over from a text editor? WordPress sometimes adds extra characters when I paste code in.
Thanks Paul, in doing some testing, it seems that even if I run the add_tree.php comnand with –list-graphs etc… it stills comes up with that odd character….
HI
Iam new to this cacti and nagios , i had installed cacti and nagios in two differnet box, how to cacti graphs in nagios. or i need to install cacti nad nagios in the same box. please suggest me.
Regards
Dinesh.M
Hello Paul.
I’m checked from command line and I got this error:
/usr/local/nagios/libexec/check_port_saturation.py -H dell5424 -C public -s “10.100.100.20” -g 2 -i 1
Traceback (most recent call last):
File “/usr/local/nagios/libexec/check_port_saturation.py”, line 77, in
main()
File “/usr/local/nagios/libexec/check_port_saturation.py”, line 47, in main
if datetime.datetime.now() – datetime.datetime.strptime(i[‘Date’], ‘%Y-%m-%d %H:%M:%S’) <= datetime.timedelta(minutes=17):
KeyError: 'Date'
Can you help me?
Thanks.
You probably can’t access graphs without logging in to Cacti. Try https://YOUR_CACTI_HOST/cacti/graph_view.php and if you get login page look at this article:
https://numpanglewat.wordpress.com/2009/07/27/how-to-view-cacti-graphics-without-login/
Hi ,
Do we really need python 2.7 ?? Won’t it be possible with python 2.6. ? getting error as
Traceback (most recent call last):
File “./check_port_saturation.py”, line 7, in
import netsnmp
ImportError: No module named netsnmp
When I run the script I am getting an error File “./check_port_saturation.py”
File “./check_port_saturation.py”, line 7, in
import netsnmp
ImportError: No module named netsnmp
helpp pls..
Hello!
>KeyError: ‘Date’
Is because unsuccessful login and gotten empty file.
I don’t know Python at all, but I managed to hack this script to use http login and snmp v3.
1. Added SNMP v3 parameters:
################################################################################
### Added by Alar Smiltinsh on 2016.08.05 for SNMP V3 authentication
################################################################################
parser.add_argument(‘-u’, ‘–snmp_secname’, default=’initial’,
help=’SNMP SecName (username) (v3)’)
parser.add_argument(‘-l’, ‘–snmp_seclevel’, default=’noAuthNoPriv’,
help=’SNMP security level [noAuthNoPriv, authNoPriv, authPriv] (v3)’)
parser.add_argument(‘-a’, ‘–snmp_authproto’, default=’MD5′,
help=’SNMP authentication protocol [MD5, SHA] (v3)’)
parser.add_argument(‘-A’, ‘–snmp_authpass’,
help=’SNMP authentication passphrase’)
#parser.add_argument(‘-x’, ‘–snmp_privproto’, default=’DES’,
parser.add_argument(‘-x’, ‘–snmp_privproto’,
help=’SNMP privacy protocol [DES] (v3)’)
parser.add_argument(‘-X’, ‘–snmp_privpass’,
help=’SNMP privacy passphrase (v3)’)
################################################################################
2.
### Commented out by Alar Smiltinsh on 2016.08.05
###text = requests.get(‘https://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’, verify=’/etc/ssl/certs/ca-certificates.crt’).content
################################################################################
### Added by Alar Smiltinsh on 2016.08.05 for HTTP (not HTTPS) login.
################################################################################
###text = requests.get(‘http://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’, auth=(‘nagios_username’, ‘XXXXXXXXXXXXX’)).content
from bs4 import BeautifulSoup
url = ‘http://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’
#Open session
s = requests.session()
http_headers = {“Referer”: url}
# Retrieve the CSRF token first
###s.get(url) # sets cookie
###csrf_token = s.cookies[‘csrf_magic’]
###print s.cookies[‘csrf_magic’]
soup = BeautifulSoup(s.get(url).text)
#csrf_token = soup.find(name=”csrf_magic”)
csrf_token = soup.find(“input”, value=True)[“value”]
#print http_headers
#print s.cookies
#print ‘——–‘
#print csrf_token
#print ‘——–‘
#print soup
#print ‘ssssssss’
# Fill in your details here to be posted to the login form.
login_data = {
‘action’: ‘login’,
‘login_username’: ‘nagious_username’,
‘login_password’: ‘XXXXXXXXXXXXXXX’,
‘__csrf_magic’: csrf_token
}
p = s.post(url, data=login_data, headers=http_headers)
# print the html returned or something more intelligent to see if it’s a successful login page.
#print p.text
# An authorised request.
text = s.get(url).content
#print text
#Close session
s.close()
#sys.exit()
################################################################################
3.
################################################################################
### Added by Alar Smiltinsh on 2016.08.05 for SNMP V3 authentication
################################################################################
if args.snmp_ver == 3 :
if args.snmp_seclevel == ‘authPriv’ :
max_speed = (netsnmp.snmpget(netsnmp.Varbind(‘.1.3.6.1.2.1.31.1.1.1.15.’ + args.if_index), DestHost=args.host, Version=args.snmp_ver, SecLevel=args.snmp_seclevel, SecName=args.snmp_secname, AuthProto=args.snmp_authproto, AuthPass=args.snmp_authpass, PrivProto=args.snmp_privproto, PrivPass=args.snmp_privpass, Community=args.snmp_com, UseNumeric=True)[0])
elif args.snmp_seclevel == ‘authNoPriv’ :
max_speed = (netsnmp.snmpget(netsnmp.Varbind(‘.1.3.6.1.2.1.31.1.1.1.15.’ + args.if_index), DestHost=args.host, Version=args.snmp_ver, SecLevel=args.snmp_seclevel, SecName=args.snmp_secname, AuthProto=args.snmp_authproto, AuthPass=args.snmp_authpass, Community=args.snmp_com, UseNumeric=True)[0])
#elif args.snmp_seclevel == ‘noAuthNoPriv’ :
#…
else : #SNMP V2
################################################################################
max_speed = (netsnmp.snmpget(netsnmp.Varbind(‘.1.3.6.1.2.1.31.1.1.1.15.’ + args.if_index), DestHost=args.host, Version=args.snmp_ver, Community=args.snmp_com, UseNumeric=True)[0])
4.
################################################################################
### Modified by Alar Smiltinsh on 2016.08.05 – added return codes for Nagios status detection
################################################################################
if (avg_inbound >= crit_threshold) or (avg_outbound >= crit_threshold) :
print ‘CRITICAL: Avgerage In = %s Mbps and Average Out = %s Mbps’ % (avg_inbound, avg_outbound)
sys.exit(2)
elif (warn_threshold <= avg_inbound) or (warn_threshold <= avg_outbound) :
print 'WARNING: Average In = %s Mbps and Average Out = %s Mbps' % (avg_inbound, avg_outbound)
sys.exit(1)
elif (0 <= avg_inbound <= warn_threshold) and (0 <= avg_outbound <= warn_threshold):
print 'OK: Average In = %s Mbps and Average Out = %s Mbps' % (avg_inbound, avg_outbound)
sys.exit(0)
else:
sys.exit(3)
################################################################################
Hi Paul,
I am working on this and I have Nagios 4.1.1 and Cacti 0.8.8f running on Ubuntu Server 16.04 LTS. I really appreciate your work and the comments of the other folks following this. The error I am seeing now is the following when I run check_port_saturation.py at the prompt:
root@NetManager:/usr/local/nagios/libexec# ./check_port_saturation.py -H 172.16.5.38 -g 11 -s 172.16.1.47 -V 2 -C R1verC0untry -i 10107
Traceback (most recent call last):
File “./check_port_saturation.py”, line 77, in
main()
File “./check_port_saturation.py”, line 60, in main
avg_inbound = round(sum(inbound) / len(inbound), 2)
ZeroDivisionError: integer division or modulo by zero
What is causing this?
Thanks,
John
Hello,
I made some little modification to script to fix this:
– When Cacti returns NaN in graph_xport, ignore this
– Return right return codes to Nagios
– I have DMZ between Nagios and Cacti so I don’t need HTTPS
— check_port_saturation.orig 2016-10-12 16:13:49.000000000 +0200
+++ /usr/lib/nagios/plugins/check_port_saturation 2016-10-12 16:01:32.678265253 +0200
@@ -1,4 +1,4 @@
-#!/opt/python/bin/python2.7
+#!/usr/bin/env python2.7
# Paul Porter 2013 http://paulgporter.net
import csv
@@ -38,18 +38,18 @@
# Download the data from Cacti. Update the cert path to match yours.
– text = requests.get(‘https://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’, verify=’/etc/ssl/certs/ca-certificates.crt’).content
+ text = requests.get(‘http://’+ args.cacti_server +’/cacti/graph_xport.php?local_graph_id=’+ args.graph_id +’&rra_id=5&view_type=’).content
# If download was successful parse the CSV file, skip the headers, and retrieve data from the Inbound and Outbound columns. Otherwise exit with an error.
if len(text) > 1 :
for i in csv.DictReader(cStringIO.StringIO(text[text.index(‘””‘) + 3:])):
– if datetime.datetime.now() – datetime.datetime.strptime(i[‘Date’], ‘%Y-%m-%d %H:%M:%S’) <= datetime.timedelta(minutes=17):
+ if datetime.datetime.now() – datetime.datetime.strptime(i['Date'], '%Y-%m-%d %H:%M:%S') = crit_threshold) or (avg_outbound >= crit_threshold) :
print ‘CRITICAL: Avg_In= %s Mbps and Avg_Out= %s Mbps’ % (avg_inbound, avg_outbound)
+ sys.exit(2)
elif (warn_threshold <= avg_inbound) or (warn_threshold <= avg_outbound) :
print 'WARNING: Avg_In= %s Mbps and Avg_Out= %s Mbps' % (avg_inbound, avg_outbound)
+ sys.exit(1)
elif (0 <= avg_inbound <= warn_threshold) and (0 <= avg_outbound <= warn_threshold):
print 'SUCCESS: Avg_In= %s Mbps and Avg_Out= %s Mbps' % (avg_inbound, avg_outbound)
+ sys.exit(0)
+ else:
+ print 'UNKNOWN: Cannot get data. avg_inbound "%s", crit_threshold "%s", avg_outbound "%s", warn_threshold "%s"' % (avg_inbound, crit_threshold, avg_outbound, warn_threshold)
+ sys.exit(3)
if __name__ == '__main__':
main()
hi. i’ve tried running the initial script and after managing to fix the spaces and stuff it was exiting with error no result but dumping the csv which looked ok to me.
i have now tried to add these last few lines and it keeps telling me that i have a syntax error in
if datetime.datetime.now() – datetime.datetime.strptime(i[‘Date’], ‘%Y-%m-%d %H:%M:%S’) = crit_threshold) or (avg_outbound >= crit_threshold) :
print ‘CRITICAL: Avg_In= %s Mbps and Avg_Out= %s Mbps’ % (avg_inbound, avg_outbound)
this line
can you help please? i’d really like to see this thing working.
thanks
hi. i’ve tried running the initial script and after managing to fix the spaces and stuff it was exiting with error no result but dumping the csv which looked ok to me.
i have now tried to add these last few lines and it keeps telling me that i have a syntax error in
if datetime.datetime.now() – datetime.datetime.strptime(i[‘Date’], ‘%Y-%m-%d %H:%M:%S’) = crit_threshold) or (avg_outbound >= crit_threshold) :
print ‘CRITICAL: Avg_In= %s Mbps and Avg_Out= %s Mbps’ % (avg_inbound, avg_outbound)
this line
can you help please? i’d really like to see this thing working.
thanks