snmpstats.pl

来自「监控软件rrdtools」· PL 代码 · 共 364 行 · 第 1/2 页

PL
364
字号
				# Anyway, it's an extensible memory structure that doesn't care what you're stuffing into it.                			foreach $key (keys %array) {		                        	$ifIndex = $key;               			        	$ifIndex =~ s/^$oids{$object}.//g;                        			$data{$device_name}{$ifIndex}{$object} = $array{$key};						#print "$device_name: ifIndex $ifIndex, $object = $data{$device_name}{$ifIndex}{$object}\n";                			} #end foreach				} #end foreach			} #end foreach		# Alright, so at this point, we should have a full set of data (whatever we requested) for 		# each active interface.		# This whole next section is all about what we do with any given piece of data, so if you're doing		# customization beyond what I've included, here's your sandbox, here's your shovel. Go build me a Buick.		# My primary goal for this utility is low overhead interface utilization tracking for my router and switch.		# In combination with RRDtool's graphing abilities, poof, it's a skimpy but solid (and extensible) replacement		# for MRTG. Don't get me wrong, I like MRTG, but RRDtool a lot easier to do flexible things with. The fact		# that this whole piece is in Perl provides a working template for bigger and crazier things, like using 		# a real SQL db for tracking port data, or real time data feeds to Linus knows what. With these things in		# mind, let's start tossing some data.		#        ifSpeed               => "1.3.6.1.2.1.2.2.1.5",		# Since we're doing traffic graphing, it's helpful to know the size of the pipe we're tracking.        	#	ifOperStatus          => "1.3.6.1.2.1.2.2.1.8",		# If the interface is down for some reason, it'd be good to have a way to represent that.        	#	ifAlias               => "1.3.6.1.2.1.31.1.1.1.18",		# ifAlias is usually a human supplied interface description. 		#       ifInErrors            => "1.3.6.1.2.1.2.2.1.14",		#       ifInOctets            => "1.3.6.1.2.1.2.2.1.10",		#       ifInUnkProtos         => "1.3.6.1.2.1.2.2.1.15",		#       ifOutDiscards         => "1.3.6.1.2.1.2.2.1.19",		#       ifOutErrors           => "1.3.6.1.2.1.2.2.1.20",		#       ifOutOctets           => "1.3.6.1.2.1.2.2.1.16"		# These should be pretty obvious. No, that's not short for Uncle Protos.		#       ifDescr               => "1.3.6.1.2.1.2.2.1.2",		# This is usually the name for an interface. Very important variable.		# Since I'm testing with a cisco catalyst, I've switched ifDescr for ifName/ifXName, up top. Less pain.		# We need a place to store this stuff, so let's check out storage structures			foreach $device_name (keys %data) {				#print "Generating/feeding data for $device_name\n";				foreach $ifIndex (keys %{$data{$device_name}}) {					$ifDescr = $data{$device_name}{$ifIndex}{'ifDescr'};					if ($ifDescr eq "") {						#print "$device_name ifIndex $ifIndex apparantly has a null ifDescr -> [$ifDescr], skipping\n";						next;					} # end if			# If you recognize where I stole these from, you may already know me as '[tHUg]Heartless'			# I prefer the Aug and the TMP, and I fear no AWP. =)			# This set of regexp's is for scrubbing potentially exciting characters from interface names before 			# using them as the basis for storing files. Some OS's and file systems may object to some of these 			# characters, so, better safe than annoyed.			# You'll note I don't provide facilities for reverting this. I just collect the stuff. Display is your problem.			    		$ifDescr =~ s/ /_/g;			    		$ifDescr =~ s/\=/\[EQUAL\]/g;			    		$ifDescr =~ s/\,/\[CMA\]/g;			    		$ifDescr =~ s/;/\[SMICLN\]/g;			   	 	$ifDescr =~ s/:/\[CLN\]/g;			  	  	$ifDescr =~ s/\"/\[DBLQT\]/g;			 	   	$ifDescr =~ s/\'/\[SNGLQT\]/g;				    	$ifDescr =~ s/\{/\[LB2\]/g;				    	$ifDescr =~ s/\}/\[RB2\]/g;				    	$ifDescr =~ s/\+/\[PLS\]/g;				    	$ifDescr =~ s/\-/\[DSH\]/g;				    	$ifDescr =~ s/\(/\[LPRN\]/g;				    	$ifDescr =~ s/\)/\[RPRN\]/g;				    	$ifDescr =~ s/\*/\[STR\]/g;				    	$ifDescr =~ s/\&/\[AND\]/g;				    	$ifDescr =~ s/\|/\[PIPE\]/g;				    	$ifDescr =~ s/\\/\[BSLSH\]/g;				    	$ifDescr =~ s/\//\[FSLSH\]/g;				    	$ifDescr =~ s/\?/\[QUESTN\]/g;				    	$ifDescr =~ s/\</\[LT\]/g;				    	$ifDescr =~ s/\>/\[GT\]/g;				    	$ifDescr =~ s/\./\[DOT\]/g;				    	$ifDescr =~ s/\!/\[XCLM\]/g;				    	$ifDescr =~ s/\@/\[AT\]/g;				    	$ifDescr =~ s/\#/\[PND\]/g;				    	$ifDescr =~ s/\$/\[DLLR\]/g;				    	$ifDescr =~ s/\%/\[\PRCNT\]/g;				    	$ifDescr =~ s/\^/\[CRT\]/g;							if ( -e "$rrd_store/$device_name-$ifDescr.rrd") {					# Uh, hey, it's there. Don't worry, be happy.					}					else {  # Oh, damn, it isn't, better create it.							# Knowing the speed of the interface, generally reported by SNMP in bits per second,			# we can fairly accurately determine how long it could take that counter to roll over,			# if it's a 32 bit counter.			# So, we'll use that info in creating the interface data. You may recognize these variables			# from the RRD tutorial docs, which were further derived from MRTG. I reuse them both because			# I'm lazy and so people will recognize what to hack on if they've beat up MRTG before.						if ($speed = $data{$device_name}{$ifIndex}{'ifSpeed'}) {							print "$device_name: Found $speed speed for $ifIndex\n";						}						else {							$speed = "U";						}							@interface_rrd = (						"DS:InBits:COUNTER:600:0:$speed",						"DS:OutBits:COUNTER:600:0:$speed",						"RRA:AVERAGE:0.5:1:600",						"RRA:AVERAGE:0.5:6:700",						"RRA:AVERAGE:0.5:24:775",						"RRA:AVERAGE:0.5:288:797",						"RRA:MAX:0.5:1:600",						"RRA:MAX:0.5:6:700",						"RRA:MAX:0.5:24:775",						"RRA:MAX:0.5:288:797"						);				# I feed the array to the create argument here, so it's easier to alter the rrd			# creation by just changing entries in the array above. Generic and reusable.						if(RRDs::create ("$rrd_store/$device_name-$ifDescr.rrd",							 "--step=300", 							 @interface_rrd)) {							print "Built RRd for $ifDescr\n";						}						else {							$ERR=RRDs::error;							print "RRd build for $ifDescr appears to have failed: $ERR\n";							next;						}					}			# Do some calculations.					$data{$device_name}{$ifIndex}{InBits} = $data{$device_name}{$ifIndex}{ifInOctets} * 8;					$data{$device_name}{$ifIndex}{OutBits} = $data{$device_name}{$ifIndex}{ifOutOctets} * 8;			# Feed the RRD our data.					$rrdfeed = join ":", ("N", 						$data{$device_name}{$ifIndex}{InBits},#      		                          	$data{$device_name}{$ifIndex}{IfInErrors},       		                         	$data{$device_name}{$ifIndex}{OutBits},#      		                          	$data{$device_name}{$ifIndex}{IfOutErrors},					);					RRDs::update ("$rrd_store/$device_name-$ifDescr.rrd",						"--template", "InBits:OutBits", 						"$rrdfeed"); 					if($ERR=RRDs::error) {						print STDERR "$rrd_store/$device_name-$ifDescr.rrd update failed: $ERR\n";					}					else {						#print "$rrd_store/$device_name-$ifDescr.rrd updated\n" if ($debug);					}				}			}	# yeah, it's sloppy, sue me.        	}        	else {		# Abort abort abort, no go no go. uNF. =)                	print STDERR "$device_name: SNMP Session failed: $error\n";        	}	}	$end = time;	$duration = $end - $start;	$sleep_period = 300 - $duration;	if($sleep_period > 0) { sleep($sleep_period) }	undef(%data);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?