The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Geneos::API - Handy Perl interface to ITRS Geneos XML-RPC Instrumentation API

VERSION

Version 0.12

SYNOPSIS

    use Geneos::API;

    # open API to NetProbe running on host example.com and port 7036
    my $api = Geneos::API->new("http://example.com:7036/xmlrpc");

    # get the sampler "Residents" in the managed entity "Zoo"
    my $sampler = $api->get_sampler("Zoo", "Residents");

    # create view "Monkeys" in the group "Animals"
    my $view = $sampler->create_view("Monkeys", "Animals");

    # prepare some data
    my $monkeys = [
        ["Name",   "Type"             ],
        ["Funky",  "Red-tailed monkey"],
        ["Cheeky", "Tibetan macaque"  ]
    ];

    # populate the view
    $view->update_entire_table($monkeys);

    # get stream "News" on sampler "Channels" in the managed entitity "Zoo"
    my $stream = $api->get_sampler("Zoo","Channels")->get_stream("News");

    # add a message to the stream
    $stream->add_message("Funky beats Cheeky in a chess boxing match!");

DESCRIPTION

Geneos::API is a Perl module that implements ITRS XML-RPC Instrumentation API. It can be used to create clients for both Geneos API and API Steams plug-ins. The plug-ins act as an XML-RPC server.

Geneos Samplers, Data Views and Streams are represented by instances of Geneos::API::Sampler, Geneos::API::Sampler::View and Geneos::API::Sampler::Stream classes. This provides easy to use building blocks for developing monitoring applications.

This module comes with its own XML-RPC module based on XML::LibXML as ITRS implementation of XML-RPC does not conform to the XML-RPC standard and therefore most of the available XML-RPC modules cannot be used. The client uses LWP::UserAgent and gives access to all the available constructor options provided by LWP::UserAgent.

The module also provides customizable error and debug hanlders.

METHODS

Constructor

$api->new($url, $options)

$url is required and must be in the format:

http://host:port/path

For example:

    my $api = Geneos::API->new("http://localhost:7036/xmlrpc");

XML-RPC Client is initialized upon call to the API constructor

Options

The constructor accepts a reference to the options hash as optional second parameter:

    my $api = Geneos::API->new("http://localhost:7036/xmlrpc", {
        api => {raise_error => 1,},
        ua  => {keep_alive=>10, timeout=>5,},
    });

api - XML-RPC options

  • raise_error

    Force errors to raise exceptions via Carp::croak

  • print_error

    Force errors to raise warnings via Carp::carp

  • error_handler

    Custom error handler. See Error handler section for more details.

  • debug_handler

    Debug handler. See Debugging section for more details.

The order of presedence for error handling is as follows:

  • error_handler

  • raise_error

  • print_error

If neither is set, the errors won't be reported and $api->error method will need to be called to check if the latest call generated an error or not.

ua - UserAgent options

Error handling

$api->raise_error()

Get the raise_error attribute value

Returns true is the raise_error attribute is set or false otherwise

If the raise_error attribute is set, errors generated by API calls will be passed to Carp::croak

$api->remove_raise_error()

Remove the raise_error attribute

$api->print_error()

Get the print_error attribute value

Returns true is the print_error attribute is set or false othersise

If the print_error attribute is set, errors generated by API calls will be passed to Carp::carp

print_error attribute is ignored if raise_error is set.

$api->remove_print_error()

Remove the print_error attribute

$api->status_line

Returns the string "<code> <message>". Returns undef if there is no error.

$api->error

Get the error produced by the last api call.

Returns reference to the error hash or undef if the last call produced no error. The hash contains three elements:

  • code

    HTTP or XML-RPC error code.

  • message

    Error string.

  • class

    The component that produced the error: HTTP or XML-RPC.

Error handler

Allows you to provide your own behaviour in case of errors.

The handler must be passed as a reference to subroutine and it could be done as a constructor option:

    my $api = Geneos::API->new("http://localhost:7036/xmlrpc", {
        api => { error_handler => \&my_error_handler, },
    });

or via a separate method:

    $api->error_handler(\&my_error_handler)

The subroutine is called with two parameters: reference to the error hash and the api object itself.

For example, to die with a full stack trace for any error:

    use Carp;
    $api->error_handler( sub { confess("$_[0]->{code} $_[0]->{message}") } );

Please note that the custom error handler overrides the raise_error and print_error settings.

The error handler can be removed by calling:

    $api->remove_error_handler()

API and API Streams Function Calls

There are two classes that represent Samplers and Views. Samplers are represented by the internal Geneos::API::Sampler class. First, a sampler object must be created:

    $sampler = $api->get_sampler($managed_entity, $sampler_name)

This will create a Sampler object representing a sampler with the name $sampler_name in the managed entity $managed_entity. You can call any method from the section "Sampler methods" on this object.

Views are represented by the internal Geneos::API::Sampler::View class. In order to create an instance of this class, you can use:

    # if the view already exists
    $view = $sampler->get_view($view_name, $group_heading)

    # if the view does not exist yet and you want to create it 
    $view = $sampler->create_view($view_name, $group_heading)

Once the view object is created, you can call any of the "View methods" on it.

Streams are represented by the internal Geneos::API::Sampler::Stream class. In order to create an instance of this class, you can use:

    $stream = $sampler->get_stream($stream_name)

Once the object is created, you can call any of the "Stream methods" on it.

Sampler methods

$api->get_sampler($managed_entity, $sampler)

This method doesn't check whether the sampler exists.

Returns sampler object.

$sampler->get_stream($stream_name)

The stream must already exist. This method will NOT check that the stream extists or not.

Returns an object representing the stream $stream_name.

$sampler->create_view($view_name, $group_heading)

Creates a new, empty view $view_name in the specified sampler under the specified $group_heading. This method will create a view and returns the object representing it. An error will be produced if the view already exists.

Returns OK on successful completion.

$sampler->get_view($view_name, $group_heading)

The view must already exist. This method will NOT check that the view extists or not. Use $sampler->view_exists method for that.

Returns an object representing the view $view_name.

$sampler->view_exists($view_name, $group_heading)

Checks whether a particular view exists in this sampler.

Returns true if the view exists, false otherwise.

$sampler->remove_view($view_name)

Removes a view that has been created with create_view.

Returns OK on successful completion.

$sampler->get_parameter($parameter_name)

Retrieves the value of a sampler parameter that has been defined in the gateway configuration.

Returns the parameter text written in the gateway configuration.

$sampler->sign_on($period)

$period - The maximum time between updates before samplingStatus becomes FAILED

Commits the API client to provide at least one heartbeat or update to the view within the time period specified.

Returns OK on successful completion.

$sampler->sign_off()

Cancels the commitment to provide updates to a view.

Returns OK on successful completion.

$sampler->heartbeat()

Prevents the sampling status from becoming failed when no updates are needed to a view and the client is signed on.

Returns on successful completion.

View methods

$view->add_table_row($row_name,$data)

Adds a new, table row to the specified view and populates it with data. Returns OK on successful completion.

$view->remove_table_row($row_name)

Removes an existing row from the specified view.

Returns OK on successful completion.

$view->add_headline($headline_name)

Adds a headline variable to the view.

Returns OK on successful completion.

$view->remove_headline($headline_name)

Removes a headline variable from the view.

Returns OK on successful completion.

$view->update_variable($variable_name, $new_value)

Can be used to update either a headline variable or a table cell. If the variable name contains a period (.) then a cell is assumed, otherwise a headline variable is assumed.

Returns OK on successful completion.

$view->update_headline($headline_name, $new_value)

Updates a headline variable.

Returns OK on successful completion.

$view->update_table_cell($cell_name, $new_value))

Updates a single cell in a table. The standard row.column format should be used to reference a cell.

Returns OK on successful completion.

$view->update_table_row($row_name, $new_value))

Updates an existing row from the specified view with the new values provided.

Returns OK on successful completion.

$view->add_table_column($column_name)

Adds another column to the table.

Returns OK on successful completion.

$view->update_entire_table($new_table)

Updates the entire table for a given view. This is useful if the entire table will change at once or the table is being created for the first time. The array passed should be two dimensional. The first row should be the column headings and the first column of each subsequent row should be the name of the row. The array should be at least 2 columns by 2 rows. Once table columns have been defined, they cannot be changed by this method.

Returns OK on successful completion.

$view->column_exists($column_name)

Check if the headline variable exists.

Returns true if the column exists, false otherwise.

$view->row_exists($row_name)

Check if the headline variable exists.

Returns true if the row exists, false otherwise.

$view->headline_exists($headline_name)

Check if the headline variable exists.

Returns true if the headline variable exists, false otherwise.

$view->get_column_count()

Return the column count of the view.

Returns the number of columns in the view. This includes the rowName column.

$view->get_row_count()

Return the headline count of the view.

Returns the number of headlines in the view. This includes the samplingStatus headline.

$view->get_headline_count()

Returns the number of headlines in the view. This includes the samplingStatus headline.

$view->get_column_names()

Returns the names of existing columns in the view. This includes the rowNames column name.

$view->get_row_names()

Returns the names of existing rows in the view

$view->get_headline_names()

Returns the names of existing headlines in the view. This includes the samplingStatus headline.

$view->get_row_names_older_than($epoch)

$epoch - The timestamp against which to compare row update time. The timestamp should be provided as Unix timestamp, i.e. number of seconds elapsed since UNIX epoch.

Returns the names of rows whose update time is older than the time provided.

Stream methods

$stream->add_message($message)

Adds a new message to the end of the stream.

Returns OK on successful completion.

NetProbe Function Calls

$api->managed_entity_exists($managed_entity)

Checks whether a particular Managed Entity exists on this NetProbe containing any API or API-Streams samplers. Returns true if the Managed Entity exists, false otherwise

$api->sampler_exists($managed_entity, $sampler)

Checks whether a particular API or API-Streams sampler exists on this NetProbe Returns true if sampler exists, false otherwise

$api->gateway_connected()

Checks whether the Gateway is connected to this NetProbe Returns true if the Gateway is connected, false otherwise

Gateway Function Calls

$api->add_managed_entity($managed_entity, $data_section)

Adds the managed entity to the particular data section Returns true on success, false otherwise

Debugging

The module comes with a debug handler. The handler must be passed as a reference to subroutine and it could be done as a constructor option:

    my $api = Geneos::API->new("http://localhost:7036/xmlrpc", {
        api => { debug_handler => \&my_debug_handler, },
    });

or via a separate method:

    $api->debug_handler(\&my_debug_handler)

The subroutine is called with one parameter: Geneos::API::XMLRPC object.

The following Geneos::API::XMLRPC methods might be useful for debugging purposes:

  • t0

    Returns the time at the start of the request. It's captured using Time::HiRes::gettimeofday method: $t0 = [gettimeofday]

  • xmlrpc_request

    Returns the Geneos::API::XMLRPC::Request object.

  • xmlrpc_response

    Returns the Geneos::API::XMLRPC::Response object.

  • http_request

    Returns the HTTP::Request object. See HTTP::Request for more details.

  • http_response

    Returns the HTTP::Response object. See HTTP::Response for more details.

The debug handler can be removed by calling:

    $api->remove_debug_handler()

Example.

The custom debug handler in this example will output the following stats:

  • Elapsed time

  • HTTP request headers

  • HTTP response headers

    use Time::HiRes qw(tv_interval);

    $api->debug_handler(\&custom_debug_handler);

    sub custom_debug_handler {
        my $api_obj = shift;

        printf "# elapsed time: %f\n\n# request header:\n%s\n# response header:\n%s\n",
               tv_interval($api_obj->t0),
               $api_obj->http_request->headers_as_string,
               $api_obj->http_response->headers_as_string;
    }

Upon execution, it will produce output similar to:

    # elapsed time: 0.002529

    # request header:
    User-Agent: libwww-perl/6.04
    Content-Type: text/xml

    # response header:
    Connection: Keep-Alive
    Server: GENEOS XML-RPC
    Content-Length: 152
    Content-Type: text/xml
    Client-Date: Fri, 26 Dec 2014 16:18:10 GMT
    Client-Peer: 127.0.0.1:9033
    Client-Response-Num: 1

ONLINE RESOURCES AND SUPPORT

BUGS

Of course. Please raise a ticket via https://rt.cpan.org/

AUTHOR

Ivan Dmitriev, <tot@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2014 by Ivan Dmitriev

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.