YATG::Retrieve::Disk - Retrieve a set of data stored by YATG::Store::Disk


YATG documentation Contained in the YATG distribution.

Index


Code Index:

NAME

Top

YATG::Retrieve::Disk - Retrieve a set of data stored by YATG::Store::Disk

DESCRIPTION

Top

You can load this module to retrieve a set of data which has previously been stored by YATG::Store::Disk. An implementation of this process is given in the CGI bundled with this distribution, which displays results of SNMP polls.

For more information on the data storage format, see YATG::Store::Disk.

USAGE

Top

There is one subroutine, retrieve() which takes seven parameters:

config

Load up your yatg_updater config using the following idiom, and pass the result in this parameter (assuming the file is named yatg.yml):

 use YATG::Config;
 YATG::Config->Defaults->{'no_validation'} = 1;

 my $yatg_conf = YATG::Config->parse('yatg.yml')
     || die 'failed to load yatg config';

 # now pass in $yatg_conf

device

This should be the IP address of a device.

port

This should be the port name, for example GigabitEthernet5/1.

leaf

This should be the SNMP leaf name (and not the OID), for example ifHCInOctets.

start

This should be a UNIX timestamp (i.e. seconds since the epoch) representing the start point for retrieved results.

end

This should be a UNIX timestamp (i.e. seconds since the epoch) representing the end point for retrieved results.

step

This parameter is optional. If not specified, the filename of the result set encodes the polling interval which will then be used for the returned results interval (i.e. one data point per step seconds returned).

Alternatively you can pass a number of seconds in this parameter and the module will do its best to provide one data point per step seconds in the returned results.

The subroutine will die if it encounters difficulty opening the data file or extracting results from it, so use an eval{}; construct or similar.

Otherwise, the return value is an array reference of results corresponding to the data points you requested with start, end and step.

SEE ALSO

Top

Tie::File::FixedRecLen

AUTHOR

Top

Oliver Gorwits <oliver.gorwits@oucs.ox.ac.uk>

COPYRIGHT & LICENSE

Top


YATG documentation Contained in the YATG distribution.

package YATG::Retrieve::Disk;

use strict;
use warnings FATAL => 'all';

use Time::Local;
use Tie::File::FixedRecLen;
use Fcntl 'O_RDONLY';
use integer;

sub retrieve {
    my ($config, $device, $port, $leaf, $start, $end, $step) = @_;
    my $root = $config->{yatg}->{disk_root};

    $port ||= 1;
    $port =~ s/[^A-Za-z0-9]/./g; # just in case, re-squash port chars

    my @files = grep {m/\d{4}-\d\d-\d\d_\d\d-\d\d-\d\dZ?,\d+$/}
                     glob("$root/$device/$leaf/$port/*");
    die "File not found at '$root/$device/$leaf/$port'\n"
        if scalar @files == 0;

    my $filename = (sort @files)[-1];
    die "File '$filename' empty!\n" unless -s $filename;

    my @store;
    tie @store, 'Tie::File::FixedRecLen', $filename,
                mode => O_RDONLY, record_length => 20;
    die "Failed to Tie::File::FixedRecLen file at '$filename'\n"
        if !tied @store;

    $filename =~ s#$root/$device/$leaf/$port/##;
    $filename =~ m/^(\d{4})-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)(Z?),(\d+)$/;

    my $base_time = $7 ?
        timegm($6,$5,$4,$3,$2-1,$1-1900) :
        timelocal($6,$5,$4,$3,$2-1,$1-1900);
    my $interval  = $8;
    my $top_time  = $base_time + ($#store * $interval);

    $step ||= $interval;
    $start = ($start - ($start % $step));
    $end   = ($end   - ($end   % $step));
    my $nudge = ($step / $interval);

    my $num_steps = (($end - $start) / $step);
    my @data = map {'0'} (0 .. ($num_steps - 1)); # fenceposts!

    my $data_offset_start =
        (($start < $base_time) ? (($base_time - $start) / $step) : 0);

    my $store_offset_start =
        (($start > $base_time) ? ((($start - $base_time) / $interval)) : 0);

    my @store_pad = map {$_} ($store_offset_start .. $#store);

    while (my @chunk = splice @store_pad,0,$nudge) {
        $data[$data_offset_start] = $store[ $chunk[-1] ] || 0;
        ++$data_offset_start;
        last if $data_offset_start > $#data;
    }

    untie @store;
    return \@data;
}

1;

__END__