git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3699 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			377 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			377 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env perl
 | 
						|
#IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
package xCAT_monitoring::rrdutil;
 | 
						|
use strict;
 | 
						|
use IO::Socket;
 | 
						|
BEGIN
 | 
						|
{
 | 
						|
	$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | 
						|
}
 | 
						|
 | 
						|
#Modules to use:
 | 
						|
use lib "$::XCATROOT/lib/perl";
 | 
						|
use xCAT::Utils;
 | 
						|
 | 
						|
################################################
 | 
						|
#sub start_RRD_server
 | 
						|
#Description:
 | 
						|
#	FOR AIX:
 | 
						|
#	add "rrdsrv $port/tcp #RRD server" to /etc/services 
 | 
						|
#	add "rrdsrv stream tcp no wait root /usr/bin/rrdtool rrdtool - $dir"
 | 
						|
#	to /etc/inetd.conf
 | 
						|
#	restart inetd
 | 
						|
#	FOR LINUX:
 | 
						|
#	add rrdsrv to xinetd
 | 
						|
#	restart xinetd
 | 
						|
#Input:
 | 
						|
#	$port	Port number of RRD server,
 | 
						|
#	$dir	directory to save *.rrd
 | 
						|
#return:
 | 
						|
#	0 success
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
sub start_RRD_server
 | 
						|
{
 | 
						|
	my ($port, $dir) = @_;
 | 
						|
	if(xCAT::Utils->isAIX()){
 | 
						|
		my $cmd = undef;
 | 
						|
		my @old = ();
 | 
						|
		my @new = ();
 | 
						|
		my $offset = 0;
 | 
						|
		my $found = 0;
 | 
						|
		@old = xCAT::Utils->runcmd("cat /etc/services", -2);
 | 
						|
		push @new, "rrdsrv $port/tcp #RRD server";
 | 
						|
		foreach (@old) {
 | 
						|
			if ($_ =~ /rrdsrv/){
 | 
						|
				if(!$found){
 | 
						|
					splice(@old, $offset, 1, @new);
 | 
						|
					$found = 1;
 | 
						|
				} else {
 | 
						|
					splice(@old, $offset, 1);
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				$offset++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	
 | 
						|
		if(!$found){
 | 
						|
			push @old, @new;
 | 
						|
		}
 | 
						|
	
 | 
						|
		open FILE, ">/etc/services.new" or return -1;
 | 
						|
		foreach (@old){
 | 
						|
			print FILE "$_\n" or return -1;
 | 
						|
		}
 | 
						|
		close FILE or return -1;
 | 
						|
		$cmd = "mv -f /etc/services.new /etc/services";
 | 
						|
		xCAT::Utils->runcmd($cmd, -2);
 | 
						|
 | 
						|
		if(! -d $dir){
 | 
						|
			$cmd = "mkdir -p $dir";
 | 
						|
			xCAT::Utils->runcmd($cmd, -2);
 | 
						|
		} else {
 | 
						|
			$cmd = "rm -rf $dir/*";
 | 
						|
			xCAT::Utils->runcmd($cmd, -2);
 | 
						|
		}
 | 
						|
		@old = ();
 | 
						|
		@new = ();
 | 
						|
		@old = xCAT::Utils->runcmd("cat /etc/inetd.conf", -2);
 | 
						|
		$offset = 0;
 | 
						|
		$found = 0;
 | 
						|
		push @new, "rrdsrv stream tcp nowait root /usr/bin/rrdtool rrdtool - $dir";
 | 
						|
		foreach (@old) {
 | 
						|
			if ($_ =~ /rrdsrv/){
 | 
						|
				if(!$found){
 | 
						|
					splice(@old, $offset, 1, @new);
 | 
						|
					$found = 1;
 | 
						|
				} else {
 | 
						|
					splice(@old, $offset, 1);
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				$offset++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if(!$found){
 | 
						|
			push @old, @new;
 | 
						|
		}
 | 
						|
		open FILE, ">/etc/inetd.conf.new" or return -1;
 | 
						|
        	foreach (@old){
 | 
						|
                	print FILE "$_\n" or return -1;
 | 
						|
        	}
 | 
						|
		close FILE or return -1;
 | 
						|
		xCAT::Utils->runcmd("mv -f /etc/inetd.conf.new /etc/inetd.conf", -2);
 | 
						|
 | 
						|
		xCAT::Utils->runcmd("stopsrc -s inetd", 0);
 | 
						|
		xCAT::Utils->runcmd("startsrc -s inetd", 0);
 | 
						|
	} elsif (xCAT::Utils->isLinux()){
 | 
						|
		if(-e "/etc/xinetd.d/rrdsrv"){
 | 
						|
			xCAT::Utils->runcmd("mv -f /etc/xinetd.d/rrdsrv /etc/xinetd.d/.rrdsrv.xcatbak",0)
 | 
						|
		}
 | 
						|
		open FILE, ">/etc/xinetd.d/rrdsrv" or return -1;
 | 
						|
		print FILE "# This is the configuration for the tcp/stream rrdsrv service.\n\n";
 | 
						|
		print FILE "service rrdsrv\n";
 | 
						|
		print FILE "{\n";
 | 
						|
		print FILE "\tdisable = no\n";
 | 
						|
		print FILE "\tport = 13900\n";
 | 
						|
		print FILE "\ttype = UNLISTED\n";
 | 
						|
		print FILE "\twait = no\n";
 | 
						|
		print FILE "\tsocket_type = stream\n";
 | 
						|
		print FILE "\tprotocol = tcp\n";
 | 
						|
		print FILE "\tuser = root\n";
 | 
						|
		print FILE "\tserver = /usr/bin/rrdtool\n";
 | 
						|
		print FILE "\tserver_args = - /var/rrd\n";
 | 
						|
		print FILE "}\n";
 | 
						|
		close FILE;
 | 
						|
		xCAT::Utils->runcmd("service xinetd restart", 0);
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
################################################
 | 
						|
#sub stop_RRD_server
 | 
						|
#Description:
 | 
						|
#	FOR AIX:
 | 
						|
#	remove "rrdsrv $port/tcp #RRD server" from /etc/services 
 | 
						|
#	remove "rrdsrv stream tcp no wait root /usr/bin/rrdtool rrdtool - $dir"
 | 
						|
#	from /etc/inetd.conf
 | 
						|
#	restart inetd
 | 
						|
#	FOR LINUX:
 | 
						|
#	remove from xinetd
 | 
						|
#	restart xinetd
 | 
						|
#Input:
 | 
						|
#	None
 | 
						|
#return:
 | 
						|
#	0 success
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
sub stop_RRD_server
 | 
						|
{
 | 
						|
	if(xCAT::Utils->isAIX()){
 | 
						|
		my @old = ();
 | 
						|
		my $offset = 0;
 | 
						|
		@old = xCAT::Utils->runcmd("cat /etc/services", -2);
 | 
						|
		foreach (@old) {
 | 
						|
			if ($_ =~ /rrdsrv/){
 | 
						|
				splice(@old, $offset, 1);
 | 
						|
			} else {
 | 
						|
				$offset++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		open FILE, ">/etc/services.new" or return -1;
 | 
						|
        	foreach (@old){
 | 
						|
                	print FILE "$_\n" or return -1;
 | 
						|
        	}
 | 
						|
		close FILE or return -1;
 | 
						|
		xCAT::Utils->runcmd("mv -f /etc/services.new /etc/services", -1);
 | 
						|
 | 
						|
		@old = ();
 | 
						|
		@old = xCAT::Utils->runcmd("cat /etc/inetd.conf", -1);
 | 
						|
		$offset = 0;
 | 
						|
		foreach (@old) {
 | 
						|
			if ($_ =~ /rrdsrv/){
 | 
						|
				splice(@old, $offset, 1);
 | 
						|
			} else {
 | 
						|
				$offset++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		open FILE, ">/etc/inetd.conf.new" or return -1;
 | 
						|
       		foreach (@old){
 | 
						|
                	print FILE "$_\n" or return -1;
 | 
						|
        	}
 | 
						|
		close FILE or return -1;
 | 
						|
		xCAT::Utils->runcmd("mv -f /etc/inetd.conf.new /etc/inetd.conf", -2);
 | 
						|
		xCAT::Utils->runcmd("stopsrc -s inetd", 0);
 | 
						|
		xCAT::Utils->runcmd("startsrc -s inetd", 0);
 | 
						|
	} elsif (xCAT::Utils->isLinux()){
 | 
						|
		if(-e "/etc/xinetd.d/.rrdsrv.xcatbak"){
 | 
						|
			xCAT::Utils->runcmd("mv -f /etc/xinetd.d/.rrdsrv.xcatbak /etc/xinetd.d/rrdsrv", 0);
 | 
						|
		} else {
 | 
						|
			xCAT::Utils->runcmd("rm -f /etc/xinetd.d/rrdsrv", 0);
 | 
						|
		}
 | 
						|
		xCAT::Utils->runcmd("service xinetd restart", 0);
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
################################################
 | 
						|
#sub runrrdcmd_remote
 | 
						|
#Description:
 | 
						|
#	Run the given RRD cmd on remote RRD server, 
 | 
						|
#	and return the output in an array.
 | 
						|
#Input:
 | 
						|
#	$cmd	RRD command
 | 
						|
#	$host	IP or hostname of RRD server
 | 
						|
#	$port	Port number of RRD server,
 | 
						|
#return:
 | 
						|
#	output of command
 | 
						|
################################################
 | 
						|
sub runrrdcmd_remote
 | 
						|
{
 | 
						|
	my($cmd,  $host, $port) = @_;
 | 
						|
 | 
						|
	my $socket = IO::Socket::INET->new
 | 
						|
		(PeerAddr=>$host,
 | 
						|
		PeerPort=>$port,
 | 
						|
		Proto=>'tcp',
 | 
						|
		Type=>SOCK_STREAM);
 | 
						|
 | 
						|
	if(! $socket){
 | 
						|
		print "ERROR: to connect with $host:$port\n";
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	print $socket "$cmd\n";
 | 
						|
	my $output = [];
 | 
						|
	my $line = undef;
 | 
						|
	while($line = <$socket>){
 | 
						|
		push @$output, $line;
 | 
						|
		if($line =~ /(OK|ERROR)/){
 | 
						|
			last;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	print $socket "quit";
 | 
						|
	close($socket);
 | 
						|
	return $output;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
################################################
 | 
						|
#sub RRD_create
 | 
						|
#Description:
 | 
						|
#	RRD_create will overwrite a RRdb if it already exists,
 | 
						|
#Input:
 | 
						|
#	$rrd	filename of RRD to create		
 | 
						|
#	$sum	if $sum != 0 to create a database file for SUMMARY information
 | 
						|
#	$step	the base interval in seconds with which data will be fed into the RRD
 | 
						|
#	$start_time the time in seconds when the first value should be added to the RRD
 | 
						|
#	$ds_type ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE
 | 
						|
#	$data_source the IP or hostname of remote host
 | 
						|
#return:
 | 
						|
#	0 sucess
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
sub RRD_create
 | 
						|
{
 | 
						|
	my ($rrd, $sum, $step, $start_time, $ds_type, $data_source) = @_;
 | 
						|
	my $output = [];
 | 
						|
	my $heartbeat = 8 * $step;
 | 
						|
	my $cmd = "create $rrd --start $start_time --step $step DS:sum:$ds_type:$heartbeat:U:U";
 | 
						|
	if($sum){
 | 
						|
		$cmd = $cmd." DS:num:$ds_type:$heartbeat:U:U";
 | 
						|
	}
 | 
						|
	#TODO: Specified custom RR archives here?
 | 
						|
	$cmd = $cmd." RRA:AVERAGE:0.5:1:244 RRA:AVERAGE:0.5:24:244 RRA:AVERAGE:0.5:168:244 RRA:AVERAGE:0.5:672:244 RRA:AVERAGE:0.5:5760:374";
 | 
						|
	if(defined($data_source)){
 | 
						|
		$output = &runrrdcmd_remote($cmd, $data_source, 13900);
 | 
						|
	} else {
 | 
						|
		@$output = xCAT::Utils->runcmd("rrdtool $cmd", 0);
 | 
						|
	}
 | 
						|
	my $line =  pop(@$output);
 | 
						|
	if($line =~ /ERROR/){
 | 
						|
		return -1;
 | 
						|
	} else {
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
################################################
 | 
						|
#sub RRD_update
 | 
						|
#Description:
 | 
						|
#	RRD_update 
 | 
						|
#Input:
 | 
						|
#	$rrd	filename of RRD to update	
 | 
						|
#	$sum	sum of all numeric metrics
 | 
						|
#	$num	number of all numeric metrics, should be null for a host metrics
 | 
						|
#	$process_time update time
 | 
						|
#	$data_source the IP or hostname of remote host
 | 
						|
#return:
 | 
						|
#	0 sucess
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
sub RRD_update
 | 
						|
{
 | 
						|
	my ($rrd, $sum, $num, $process_time, $data_source) = @_;
 | 
						|
	my $output = [];
 | 
						|
	my $cmd = "update $rrd";
 | 
						|
	if($num ne "null"){
 | 
						|
		$cmd = $cmd." $process_time:$sum:$num";
 | 
						|
	} else {
 | 
						|
		$cmd = $cmd." $process_time:$sum";
 | 
						|
	}
 | 
						|
	if(defined($data_source)){
 | 
						|
		$output = &runrrdcmd_remote($cmd, $data_source, 13900);
 | 
						|
	} else {
 | 
						|
		@$output = xCAT::Utils->runcmd("rrdtool $cmd", 0);
 | 
						|
	}
 | 
						|
	my $line =  pop(@$output);
 | 
						|
	if($line =~ /ERROR/){
 | 
						|
		return -1;
 | 
						|
	} else {
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
################################################
 | 
						|
#sub RRD_fetch
 | 
						|
#Description:
 | 
						|
#	RRD_fetch 
 | 
						|
#Input:
 | 
						|
#	$rrd	filename of RRD to update
 | 
						|
#	$start_time start of time series
 | 
						|
#	$end_time end of time series
 | 
						|
#	$data_source	the IP or hostname of remote host
 | 
						|
#return:
 | 
						|
#	0 sucess
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
sub RRD_fetch
 | 
						|
{
 | 
						|
	my ($rrd, $start_time, $end_time, $data_source) = @_;
 | 
						|
	my $output = [];
 | 
						|
	my $resolution = undef;
 | 
						|
	my $cmd = undef;
 | 
						|
	$cmd = "fetch $rrd AVERAGE -s $start_time -e $end_time";
 | 
						|
	if(defined($data_source)){
 | 
						|
		$output = &runrrdcmd_remote($cmd, $data_source, 13900);
 | 
						|
	} else {
 | 
						|
		@$output = xCAT::Utils->runcmd("rrdtool $cmd", 0);
 | 
						|
	}
 | 
						|
	return $output;
 | 
						|
}
 | 
						|
 | 
						|
################################################
 | 
						|
#sub push_data_to_rrd
 | 
						|
#Description:
 | 
						|
#	push_data_to_rrd
 | 
						|
#Input:
 | 
						|
#	$rrd	filename of RRD to update
 | 
						|
#	$sum	sum of all numeric metrics
 | 
						|
#	$num	number of all numeric metrics, should be null for a host metrics
 | 
						|
#	$step	the base interval in seconds with which data will be fed into the RRD
 | 
						|
#	$process_time update time
 | 
						|
#	$ds_type ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE
 | 
						|
#	$data_source	the IP or hostname of remote host
 | 
						|
#return:
 | 
						|
#	0 sucess
 | 
						|
#	!0 fail
 | 
						|
################################################
 | 
						|
 | 
						|
sub push_data_to_rrd
 | 
						|
{
 | 
						|
	my $ret = 0;
 | 
						|
	my($rrd, $sum, $num, $step, $process_time, $ds_type, $data_source) = @_;
 | 
						|
	my $summary = $num eq 'null' ? 0 : 1;
 | 
						|
	if(! -f $rrd){
 | 
						|
		$ret = RRD_create($rrd, $summary, $step, $process_time-$step, $ds_type, $data_source);
 | 
						|
		if($ret != 0){
 | 
						|
			return $ret;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	$ret = RRD_update($rrd, $sum, $num, $process_time, $data_source);
 | 
						|
	return $ret;
 | 
						|
}
 | 
						|
 | 
						|
1;
 |