NAME
    PoCo::RRDTool - POE interface to Tobias Oetiker's RRDTool

SYNOPSIS
      use POE qw( Component::RRDTool );

      my $alias = 'controller';

      my @create_args = qw(
          test.rrd
          --start now
          --step 30
          DS:X:GAUGE:60:0:10
          RRA:MAX:0.5:1:1
      );

      # start up the rrdtool component
      POE::Component::RRDTool->new(  
          Alias      => $alias,
          RRDtool    => '/usr/local/bin/rrdtool',
          ErrorEvent => 'rrd_error',
          StatusEvent=> 'rrd_status',
      );

      POE::Session->create(
          inline_states => {
              _start => sub {
                   # set a session alias so that we can receive events from RRDTool
                   $_[KERNEL]->alias_set($_[ARG0]);

                   # create a round robin database
                   $_[KERNEL]->post( 'rrdtool', 'create', @create_args );

                   # stop the rrdtool component
                   $_[KERNEL]->post( 'rrdtool', 'stop' );
              },
              'rrd_error' => sub {
                  print STDERR "ERROR: " . $_[ARG0] . "\n";
              },
              'rrd_status' => sub {
                   my ($user, $system, $real) = @_[ARG0 .. ARG2];
                   print "u: $user\ts: $system\tr: $real\n";
              },
          },
          args => [ $alias ],
      );

      $poe_kernel->run();

DESCRIPTION
    RRDtool refers to round robin database tool. Round robin databases have
    a fixed number of data points in them and contain a pointer to the
    current element. Since the databases have a fixed number of data points
    the database size doesn't change after creation. RRDtool allows you to
    define a set of archives which consolidate the primary data points in
    higher granularity. RRDtool is specialized for time series data and can
    be used to create RRD files, update RRDs, retreive data from RRDs, and
    generate graphs from the databases. This module provides a POE wrapper
    around the rrdtool command line interface.

METHODS
    new - creates a POE RRDTool component
    new() is the constructor for POE::Component::RRDTool. The constructor is
    PoCo::RRDTool's only public method. It has two optional named parameters
    alias and rrdtool.

    The alias parameter is the alias of the session that the PoCo::RRDTool
    instance will send events to as callbacks. It defaults to component. It
    is important to understand that an RRDTool instance ALWAYS uses the
    rrdtool alias to reference itself. Events are posted to the rrdtool
    alias and callbacks are posted to the alias set via the constructor.

    The rrdtool parameter is the name of the RRDTool command line utility.
    It defaults to /usr/local/bin/rrdtool.

    In the calling convention below the "[]"s indicate optional parameters.

        POE::Component::RRDTool->new(
            [-alias       => 'controller'],
            [-rrdtool     => '/usr/local/bin/rrdtool'],
            [-errorevent  => 'error_handler'],
            [-statusevent => 'status_handler'],
        );

EVENTS
    PoCo::RRDTool events take the same parameters as their rrdtool
    counterpart. Use the RRDTool manual as a reference for rrdtool command
    parameters.

    The following events can be posted to an RRDtool component.

    create - create a round robin database
            my @create_args = qw(
                test.rrd
                --start now
                --step 30
                DS:X:GAUGE:60:0:10
                RRA:MAX:0.5:1:1
            );
    
            $_[KERNEL]->post( qw( rrdtool create ), @create_args);

    update - update a round robin database
            $_[KERNEL]->post( qw( rrdtool update test.rrd N:1 ) );

    fetch - fetch data from a RRD
            my $callback = 'rrd_fetch_handler';

            my @fetch_args = qw( 
                test.rrd 
                MAX
                --start -1s
            );

            $_[KERNEL]->post( qw( rrdtool fetch ), $callback, @fetch_args );

    graph - generate a graph image from RRDs
            my $callback = 'rrd_graph_handler';

            my @graph_args = (
                '-',
                '--start', -86400,
                '--imgformat', 'PNG',
                'DEF:x=test.rrd:X:MAX',
                'CDEF:y=1,x,+',
                'PRINT:y:MAX:%lf',
                'AREA:x#00FF00:test_data',
            );

            $_[KERNEL]->post( qw( rrdtool udpate ), $callback, @graph_args );

            sub rrd_graph_handler {
                my $graph = $_[ARG0];

                printf("Image Size: %dx%d\n", $graph->{xsize}, $graph->{ysize});

                printf("PRINT output: %s\n", join('\n', @$graph->{output}) if @$graph;

                print "creating image example.png\n";
                open IMAGE, "> example.png" or die $!;
                binmode(1);
                print IMAGE $graph->{image};
                close IMAGE;
            }

    info - get information about a RRD
            my $callback = 'rrd_info_handler';

            $_[KERNEL]->post( qw( rrdtool info ), $callback, 'test.rrd' );

    xport - generate xml reports from RRDs
            my $callback = 'rrd_xport_handler';

            my @xport_args = (
              '--start', -300,
              '--step', 300,
              'DEF:x=test.rrd:X:MAX',
              'XPORT:x:foobar',
            );

            $_[KERNEL]->post( qw( rrdtool xport ), $callback, @xport_args );

    dump - dump a RRD in XML format
            my $callback = 'rrd_dump_handler';

            $_[KERNEL]->post( qw( rrdtool dump ), $callback, 'test.rrd' );

    stop - stop an RRDTool component
            $_[KERNEL]->post( qw( rrdtool stop ) );

CALLBACKS
    The callbacks listed below are sent by the RRDTool component to the
    session alias passed to it's constructor. You can provide event handlers
    for them in the controlling session's constructor. However it is not
    required to handle any of the callbacks.

    rrd_status - notification of rrdtool runtimes
    Returns the user, system, and real time of the rrdtool process in ARG0,
    ARG1, and ARG2 respectively. This event name can be overriden by using
    the StatusEvent parameter to PoCo::RRDTool->new();

        POE::Session->create(
            inline_states => {
                'rrd_status' => sub {
                    my ($user, $system, $real) = @_[ARG0 .. ARG2];
                    print "u: $user\ts: $system\tr: $real\n";
                },
                ....,
            }
        );

    rrd_error - rrdtool error notification
    Returns error messages returned from rrdtool in ARG0.

        POE::Session->create(
            inline_states => {
                'rrd_error' => sub {
                    my $error = $_[ARG0];
                    print "Error: $error\n";
                },
                ....,
            }
        );

    rrd_stopped - rrdtool process stopped
    This callback provides a hook to do something when the rrdtool process
    is stopped.

        POE::Session->create(
            inline_states => {
                'rrd_stopped' => sub {
                    print "rrdtool stopped\n";
                },
                ....,
            }
        );

AUTHOR
    Todd Caine <todd@pobox.com>

SEE ALSO
    An RRDTool Tutorial
    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/tutorial/rrdtutorial.
    html

    The Main RRDTool Website
    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/index.html

    The RRDTool Manual
    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/index.html

BUGS
    The rrdtool command line utility is being controlled by POE::Wheel::Run.
    I'm increasing the block size on the POE::Driver::SysRW instance used
    for the rrdtool output so that each command generates only one event.
    This should probably be fixed by using the default block size and a
    custom filter instead.

    If you notice that more than one event is being generated from a single
    rrdtool command you may need to increase the blocksize used.

COPYRIGHT AND LICENSE
    Copyright (c) 2002 Todd Caine. All rights reserved. This program is free
    software; you can redistribute it and/or modify it under the same terms
    as Perl itself.

