commit
This commit is contained in:
240
debian/smokeping/usr/share/perl5/Smokeping/probes/FTPtransfer.pm
vendored
Normal file
240
debian/smokeping/usr/share/perl5/Smokeping/probes/FTPtransfer.pm
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
package Smokeping::probes::FTPtransfer;
|
||||
|
||||
=head1 301 Moved Permanently
|
||||
|
||||
This is a Smokeping probe module. Please use the command
|
||||
|
||||
C<smokeping -man Smokeping::probes::FTPtransfer>
|
||||
|
||||
to view the documentation or the command
|
||||
|
||||
C<smokeping -makepod Smokeping::probes::FTPtransfer>
|
||||
|
||||
to generate the POD document.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use base qw(Smokeping::probes::passwordchecker);
|
||||
use Net::FTP;
|
||||
use Time::HiRes qw(gettimeofday sleep);
|
||||
use Carp;
|
||||
|
||||
my $DEFAULTINTERVAL = 1;
|
||||
|
||||
sub pod_hash {
|
||||
return {
|
||||
name => <<DOC,
|
||||
Smokeping::probes::FTPtransfer - intrusive bandwidth probe
|
||||
DOC
|
||||
overview => <<DOC,
|
||||
This probe send and retrieve files to or from an ftp server. It will plot
|
||||
the bandwidth it could use.
|
||||
DOC
|
||||
description => <<DOC,
|
||||
The probe uses the Net::FTP perl client to run performance tests using an
|
||||
FTP server as a target. This probe is B<intrusive> as it transfers real
|
||||
data. By using real data we get a fair shot at figuring out what a link is
|
||||
capable of when it comes to transferring actual files.
|
||||
|
||||
The password can be specified either (in order of precedence, with
|
||||
the latter overriding the former) in the probe-specific variable
|
||||
`password', in an external file or in the target-specific variable
|
||||
`password'. The location of this external file is given in the probe-specific
|
||||
variable `passwordfile'. See Smokeping::probes::passwordchecker(3pm) for the
|
||||
format of this file (summary: colon-separated triplets of the form
|
||||
`<host>:<username>:<password>')
|
||||
|
||||
The probe tries to be nice to the server and waits at least X seconds
|
||||
between starting filetransfers, where X is the value of the probe
|
||||
specific `min_interval' variable ($DEFAULTINTERVAL by default).
|
||||
|
||||
Many variables can be specified either in the probe or in the target definition,
|
||||
the target-specific variable will override the prove-specific variable.
|
||||
|
||||
If your transfer takes a lot of time, you may want to make sure to set the
|
||||
B<timeout> and B<max_rtt> properly so that smokeping does not abort the
|
||||
transfers of limit the graph size.
|
||||
DOC
|
||||
authors => <<'DOC',
|
||||
Tobias Oetiker <tobi@oetiker.ch> sponsored by Virtela
|
||||
DOC
|
||||
bugs => <<DOC,
|
||||
This probe has the capability for saturating your links, so don't use it
|
||||
unless you know what you are doing.
|
||||
|
||||
The FTPtransfer probe measures bandwidth, but we report the number of
|
||||
seconds it took to transfer the 'reference' file. This is because currently
|
||||
the notion of I<Round Trip Time> is at the core of the application. It would
|
||||
take some re-engineering to split this out in plugins and thus make it
|
||||
configurable ...
|
||||
DOC
|
||||
}
|
||||
}
|
||||
|
||||
# returns the last part of a path
|
||||
sub _get_filename ($) {
|
||||
return (split m|/|, $_[0])[-1];
|
||||
}
|
||||
|
||||
sub ProbeDesc ($) {
|
||||
my $self = shift;
|
||||
my $srcfile = $self->{properties}{srcfile};
|
||||
my $destfile = $self->{properties}{destfile} || _get_filename $self->{properties}{srcfile};
|
||||
my $mode = $self->{properties}{mode};
|
||||
my $size = $mode eq 'get' ? -s $destfile : -s $srcfile;
|
||||
return sprintf("FTP File transfers (%.0f KB)",$size/1024);
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub pingone {
|
||||
my $self = shift;
|
||||
my $target = shift;
|
||||
my $host = $target->{addr};
|
||||
my $vars = $target->{vars};
|
||||
my $mininterval = $self->{properties}{min_interval};
|
||||
my $srcfile = $self->{properties}{srcfile};
|
||||
my $destfile = $self->{properties}{destfile} || _get_filename $self->{properties}{srcfile};
|
||||
my $mode = $self->{properties}{mode};
|
||||
my $username = $vars->{username};
|
||||
|
||||
$self->do_log("Missing FTP username for $host"), return
|
||||
unless defined $username;
|
||||
|
||||
my $password = $self->password($host, $username) || $vars->{password};
|
||||
|
||||
$self->do_log("Missing FTP password for $host/$username"), return
|
||||
unless defined $password;
|
||||
|
||||
my @options = ();
|
||||
push (@options, Timeout => $vars->{timeout});
|
||||
push (@options, Port => $vars->{port} ) if $vars->{port};
|
||||
push (@options, LocalAddr => $vars->{localaddr} ) if $vars->{localaddr};
|
||||
push (@options, Passive => 1 ) if $vars->{passive} and $vars->{passive} eq 'yes';
|
||||
|
||||
my @times;
|
||||
my $elapsed;
|
||||
|
||||
for (1..$self->pings($target)) {
|
||||
if (defined $elapsed) {
|
||||
my $timeleft = $mininterval - $elapsed;
|
||||
sleep $timeleft if $timeleft > 0;
|
||||
}
|
||||
my $ftp = Net::FTP->new($host, @options) or
|
||||
$self->do_log("Problem with $host: ftp session $@"), return;
|
||||
$ftp->login($username,$password) or
|
||||
$self->do_log("Problem with $host: ftp login ".$ftp->message), return;
|
||||
my $start = gettimeofday();
|
||||
my $ok;
|
||||
my $size;
|
||||
if ($mode eq 'get'){
|
||||
$ok = $ftp->get($srcfile,$destfile) or
|
||||
$self->do_log("Problem with $host: ftp get ".$ftp->message);
|
||||
$size = -s $destfile;
|
||||
} else {
|
||||
$ok = $ftp->put($srcfile,$destfile) or
|
||||
$self->do_log("Problem with $host: ftp put ".$ftp->message);
|
||||
$size = -s $srcfile;
|
||||
}
|
||||
my $end = gettimeofday();
|
||||
$ftp->quit;
|
||||
$elapsed = ( $end - $start );
|
||||
$ok or next;
|
||||
$self->do_debug("$host - $mode mode transferred $size Bytes in ${elapsed}s");
|
||||
push @times, $elapsed;
|
||||
}
|
||||
return sort { $a <=> $b } @times;
|
||||
}
|
||||
|
||||
sub probevars {
|
||||
my $class = shift;
|
||||
my $h = $class->SUPER::probevars;
|
||||
delete $h->{timeout}{_default}; # force a timeout to be defined
|
||||
$h->{timeout}{_doc} = <<DOC;
|
||||
The timeout is the maximum amount of time you will allow the probe to
|
||||
transfer the file. If the probe does not succeed to transfer in the time specified,
|
||||
it will get killed and a 'loss' will be logged.
|
||||
|
||||
Since FTPtransfer is an invasive probe you should make sure you do not load
|
||||
the link for more than a few seconds anyway. Smokeping currently has a hard
|
||||
limit of 180 seconds for any RTT.
|
||||
DOC
|
||||
|
||||
return $class->_makevars($h, {
|
||||
_mandatory => [ 'srcfile','mode','timeout' ],
|
||||
srcfile => {
|
||||
_doc => <<DOC,
|
||||
The name of the source file. If the probe is in B<put> mode, this file
|
||||
has to be on the local machine, if the probe is in B<get> mode then this
|
||||
file should sit in the remote ftp account.
|
||||
DOC
|
||||
_example => 'src/path/mybig.pdf',
|
||||
},
|
||||
destfile => {
|
||||
_doc => <<DOC,
|
||||
Normally the destination filename is the same as the source filename
|
||||
(without the path). If you want keep files in different directories this may not
|
||||
work, and you have to specify destfile as well.
|
||||
DOC
|
||||
_example => 'path/to/destinationfile.xxx',
|
||||
},
|
||||
mode => {
|
||||
_doc => <<DOC,
|
||||
The ftp probe can be in either put or get mode. If it is in put mode then it will send a file to the ftp server. In get mode it will retrieve a file
|
||||
from the ftp server.
|
||||
DOC
|
||||
_example => 'get',
|
||||
_re => '(put|get)',
|
||||
},
|
||||
|
||||
min_interval => {
|
||||
_default => $DEFAULTINTERVAL,
|
||||
_doc => "The minimum interval between each starting ftp sessions in seconds.",
|
||||
_re => '(\d*\.)?\d+',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
sub targetvars {
|
||||
my $class = shift;
|
||||
return $class->_makevars($class->SUPER::targetvars, {
|
||||
username => {
|
||||
_doc => 'The username to be tested.',
|
||||
_example => 'test-user',
|
||||
},
|
||||
password => {
|
||||
_doc => 'The password for the user, if not present in the password file.',
|
||||
_example => 'test-password',
|
||||
},
|
||||
timeout => {
|
||||
_doc => "Timeout in seconds for the FTP transfer to complete.",
|
||||
_re => '\d+',
|
||||
_example => 10,
|
||||
},
|
||||
port => {
|
||||
_doc => 'A non-standard FTP port to be used',
|
||||
_re => '\d+',
|
||||
_example => '3255',
|
||||
},
|
||||
localaddr => {
|
||||
_doc => 'The local address to be used when making connections',
|
||||
_example => 'myhost-nat-if',
|
||||
},
|
||||
passive => {
|
||||
_doc => 'Use passive FTP protocol',
|
||||
_re => '(yes|no)',
|
||||
_example => 'yes',
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user