The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Async::Graphite::API - Interface between perl and graphite.

SYNOPSIS

    with 'Net::Async::Graphite::API';

DESCRIPTION

Don't use this module directly, use Net::Async::Graphite and create objects using its new method in the normal way. Those objects will include the functionality documented here.

This role brings the capacity to transmit HTTP requests to graphite and asynchronously wait for and return the response.

It also defines a structure describing complex target paths in a perl data structure.

BUGS

Assumes graphite-api and doesn't handle transport errors at all.

Using Memoize may be pointles.

ROLE

Asynchronity is achieved by using Net::Async::HTTP inside Net::Async::Graphite::HTTPClient.

JSON data is decoded using a JSON object handled by Net::Async::Graphite::JSONCodec.

ATTRIBUTES

endpoint (required, read-only)

The base of the graphite URL to which /metrics and /render requests will be directed. Everything up to and including the trailing /. eg. https://monitoring.example.com:8080/graphite/.

If the trailing / is not included it's assumed you know what you're doing so only a warning will be printed.

PUBLIC METHODS

All of these methods return a Future which will complete with the indicated result (or which will die).

metrics ($method, $query, [%extra])

Perform $method on/with the metrics which match $query, which should be a simple scalar describing the query to perform, or an arrayref of such scalars if the method can handle multiple query parameters. ie. this will request a URI which looks like: <graphite-endpoint>/metrics/<$method>?query=<$query>[&query=...]. If arguments are supplied in %extra, they are added to the generated URI as encoded query parameters.

The three methods which graphite-api exposes at this time are supported:

find
expand
index[.json]

/metrics/index.json can be requested with $method of index or index.json because requiring the .json suffix is silly. Also I can consider creating real methods find, expand and index.

The Future will complete with the http content. If you want the HTTP request object see the _download private method, but note private.

metrics_asperl ($method, $query, [%extra])

Calls metrics() with the same arguments and decodes the result, which is assumed to be JSON text, into a perl data structure.

render ($format, $target, [%extra])

Fetch the metric data for the given $target, which should be a simple scalar specifying a path identifying metrics, or an arrayref of such scalars, as described in the graphite /render documentation render() will then request a URI which looks like: <graphite-endpoint>/render?format=<$format>&target=<$query>[&target=...].

The name of the format may also be called as a method directly, without the first ($format) argument:

csv ($target, [%extra])
dygraph ($target, [%extra])
json ($target, [%extra])
pdf ($target, [%extra])
png ($target, [%extra])
raw ($target, [%extra])
rickshaw ($target, [%extra])
svg ($target, [%extra])
render_asperl ($target, [%extra])

Calls render() with the same arguments but prepended by the format raw, and decodes the result.

Graphite's raw format is documented in graphite /render documentation but in short it's an ASCII (or UTF-8 if you're so inclined) encoded file consisting of one line per metric found. Each line consists of a header and the data separated by a |. Within each of these each datum is separated by a ,.

I don't know or care if the line endings include \r.

The data is returned as a list of hashrefs containing the data broken up into all of its components. ie. Each datum of each metric will be turned into its own perl scalar.

Each hashref will contain five values:

target

The path of metric.

start

Unix timestamp pinpointing the beginning of the data.

end

Unix timestamp pinpointing the end of the data.

step

The time interval in seconds (probably) between each datum.

data

The data. An arrayref of however many scalars it takes.

The data are not converted from their original text form, and graphite include the string None in the list of returned values, so not every datum will necessarily look like a number.

find_target_from_spec ($spec, ...)

Construct strings for use by the target parameter of /render queries from the specifications in each $spec, which must be a plain text scalar of the metric's path or an arrayref containing 2 items (second optional):

$function

The name of a function as defined by the graphite API.

[ @arguments ] (optional)

An arrayref containing 0 or more arguments. Each argument may be a scalar, which left alone, or an arrayref which must itself be another $spec-like scalar/pair.

It sounds a lot more confusing than it is. These are valid:

    # Scalar

    'simple.metric.name'

    # Becomes "simple.metric.name"


    # Function

    [ 'summarize' => [ 'simple.metric.name' ] ]

    # Becomes "summarize(simple.metric.name)"


    # Function with more arguments

    [ 'summarize' => [ 'me.tr.ic', '"arg1"', 42 ] ]

    # Becomes "summarize(me.tr.ic,%52arg1%52,42)"


    # Recursive function

    [
        'summarize' => [
            'randomize' => [
                'pointless.metric', 'argue', 'bicker'
            ],
            'and-fight',
        ]
    ]

    # Becomes "summarize(randomize(pointless.metric,argue,bicker),and-fight)"

Any other form is not.

Simply put, where it's not just a plain string the specification is a recursive nest of function/argument-list pairs, where each argument can itself be another function pair.

The implementation of the target string construction uses Memoize to avoid repeatedly calling functions which return the same data. It probably destroys any advantage gained by doing this by normalising the function arguments with JSON first. I'll measure it some day.

PRIVATE METHODS

__construct_target_argument ($argument)

This is not an object or class method.

Compile $argument into its part of the string which will build up the (or a) target component of a Graphite request URI. $argument must be a scalar or an arrayref with exactly one or two items in it. If included, the second must be an arrayref of the function's arguments.

Returns the scalar as-is or calls __construct_target_function to decode the arrayref.

This function uses Memoize for which it normalises its arguments using JSON.

__construct_target_function ($name, [@arguments])

This is not an object or class method.

Compile $name and @arguments into their part of the string which will build up the target component of a Graphite request URI. Recurses back into __construct_target_argument to build each argument component.

This function uses Memoize for which it normalises its arguments using JSON.

SEE ALSO

Graphite's /render documentation http://graphite.readthedocs.io/en/latest/render_api.html

Net::Async::Graphite

Net::Async::Graphite::HTTPClient

Net::Async::Graphite::JSONCodec

Future

Moo

Net::Async::HTTP

AUTHOR

Matthew King <matthew.king@cloudbeds.com>