README for traffic.pl By Dave Kelly (dk@lucidstrategies.net) LICENSE: You've got to be kidding me. I would appreciate it if credit to me, the original author, was left in there, but I'm not going to send anyone to your house to break your arms if you don't. God knows I've used enough free software in my life that I should give something back anyway. However, if this program breaks your computer or shoots your dog or something like that, I'm telling you right now I'm not liable for it. Someday, I'll officially make this GPL. Until then, do what you want with it. HISTORY: This script came about because we had a customer who wanted to broadcast a radio station over the Internet. Since these kinds of applications tend to use a lot of bandwidth, we wanted to make sure we knew exactly how much they were using every month, so we could bill them accordingly. So I wrote this program in perl, originally as a standalone program. The key problem I had to overcome is that if you are watching counters on a switch or a router, they will roll over at some set threshold, usually 2^32. When you're talking about a switch pushing hundreds of gigabytes a month, it's not uncommon for it to roll over at least once a day, if not much more. So the logic behind this program is thus: - When you first start monitoring a port, store the initial counter values. Since I want to monitor both in and out bytes, I store both. This number becomes our initial offset. - Store a value that holds the number of times the counter has rolled over since the last "reset" of your monitoring. Initially, this is zero. - Each time we update, we want to store the current amount as the "last updated value". - On each update, if the current counter value is less than the last updated value we stored from the previous update, we know the counter has rolled, and we need to increment our rollover count. - To calculate total bandwidth used, we take (number of rollovers * rollover threshold). We then subtract the initial offset, effectively basing our current number from zero. Then we add the current counter value. This final number is the total bytes that have passed through that counter since the last time our monitor reset it's count. All offsets, last values, rollover counts, etc. are stored in a gdb file. Hashing it makes it quicker and easier to manage with PERL, so that's why I did it. I'm always open to better ways of doing it if you have any. Then I simply fired off a cron job to run a shell script just before midnight on the last 4 days of every month. In the shell script, it checks to see if it's the LAST day of the month, and if it is, the script calls the traffic.pl script to reset the values I keep for offsets and last values, and mails me the final results to me before it resets them. This seems to work fairly well. Well, one day, I decided that it would be infinitely more handy to have this integrated into Cricket instead. So I sat down and modified what I had originally written and turned it into a script that could be called from an EXEC in Cricket as long as you pass it the right parameters. USAGE: 1) Updating new values (or creating new entries if they're not there): traffic.pl update name - This is just a reference name that makes it easy to remember. ip - The IP of the router or switch you're querying community - This is your SNMP community string inOID - This is the OID for the incoming bytes for this port or connection outOID - This is the OID for the outgoing bytes for this port or connection I realize it sucks to pass all this crap out to an external script. If anyone has a better way, please let me know! The output from this command is two lines, the first being the incoming bytes since the last reset, and the second being the outgoing. 2) Resetting stored values back to zero (at the beginning of the month, or whenever you want to do it): traffic.pl reset This command resets all the internal counters (stored in the gdb file) back to zero. This is called whenever you want your total count to reset. I do this once a month, since I want usage for an entire month. 3) Resetting a single entry back to zero: traffic.pl resetentry This command resets the internal counters (stored in the gdb file) back to zero ONLY for the entry you pass in . 4) Listing all current stored values in the database: traffic.pl listall This command lists the current counter numbers stored for each counter you're tracking. It spits the numbers out to stdout. This will look exactly like the report you get when you do a reset, except that it won't reset any of the counters back to zero. This is very useful for checking exact usage throughout the month without worrying about blowing out the month's data. 5) Deleting old entries that you don't use anymore (so they stop showing up on your month-end report): traffic.pl delete This command will delete the stored values and keys for a particular counter that you've defined. Remember if you delete a key to take it out of Cricket first, or the next time Cricket runs, it will re-add it! 6) Dumping the names of all the keys stored in the database: traffic.pl dumpdb This just dumps the names of the DB keys that are currently stored in the database. It's probably not useful for anything except debugging. SHUT UP ALREADY, HOW DO I RUN THIS THING? - Copy the scripts (traffic.pl and trafficreset.sh) to your ~cricket/cricket/util directory. - Edit them and make sure your path to PERL is correct, as well as the path for the gdb file and rootdir - Edit your Defaults and Targets entries (see below) - Add this line to the cron at whatever interval you want it reset: ~cricket/cricket/util/trafficreset.sh (FYI, here is the cron entry that I use...it runs each of the last 4 days of the month...the script takes care of knowing which one of those is actually the last day): 59 23 27-31 * * ~cricket/cricket/util/trafficreset.sh - If you want the totals emailed to you on every reset, change the "traffic.pl reset" line in trafficreset.sh to the following: /home/cricket/cricket/util/traffic.pl reset | mail -s "subject" user@mydomain.com - If you want to see the actual numbers sometime without resetting them: ~cricket/cricket/util/traffic.pl listall SAMPLE DEFAULTS FILE: --------------------------------------- Target --default-- directory-desc = "Usage Statistics for DSL customers" snmp-host = %router% snmp-community = something besides public, for God's sake target-type = DSL datasource --default-- rrd-ds-type = GAUGE rrd-heartbeat = 1800 rrd-min = undef rrd-max = undef datasource inOctets ds-source = exec:0:"~cricket/cricket/util/traffic.pl update %name% %router% %snmp-community% %inOID% %outOID%" datasource outOctets ds-source = exec:1:"~cricket/cricket/util/traffic.pl update %name% %router% %snmp-community% %inOID% %outOID%" targetType DSL ds = "inOctets, outOctets" view = "Usage: inOctets outOctets" graph inOctets color = dark-green draw-as = AREA y-axis = "Incoming bytes" legend = "Incoming bytes" graph outOctets color = blue y-axis = "Outgoing bytes" legend = "Outgoing bytes" --------------------------------------- SAMPLE TARGETS FILE: --------------------------------------- target --default-- router = 1.2.3.4 target-type = DSL target VCI_33 name = VCI_33 inOID = .1.3.6.1.4.1.9.9.66.1.1.1.1.3.8.1.33 outOID = .1.3.6.1.4.1.9.9.66.1.1.1.1.4.8.1.33 short-desc = "DSL Router - VCI 33" target Switch_Port_23 name = Switch_Port_23 inOID = interfaces.ifTable.ifEntry.ifInOctets.23 outOID = interfaces.ifTable.ifEntry.ifOutOctets.23 short-desc = "Switch Port 23" --------------------------------------- Please send feedback, enhancements, suggestions, criticism, patches, checks, money orders, etc to me at dk@lucidstrategies.net!