package Graphite::Simple;

use 5.026;
use strict;
use warnings;
use base qw/ Exporter /;

our %EXPORT_TAGS = ( 'all' => [ ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();

our $VERSION = '0.01';

require XSLoader;
XSLoader::load('Graphite::Simple', $VERSION);

1;
__END__
=encoding utf8

=head1 Graphite::Simple

Perl package provides methods to collect metrics and send them to Graphite server.

=head1 SYNOPSIS

  use Graphite::Simple ();

  my $graphite = Graphite::Simple->new(\%options);

  $graphite->connect();

  $graphite->disconnect();

  my $bulk = $graphite->get_bulk_metrics();

  my $status = $graphite->send_bulk();

  my $status = $graphite->send_bulk_delegate();

  my $metrics = $graphite->get_metrics();

  my $avg_counters = $graphite->get_average_counters();

  $graphite->clear_bulk();

  $graphite->incr_bulk($key, $value);
  $graphite->incr_bulk($key);

  $graphite->append_bulk($hash, $prefix);
  $graphite->append_bulk($hash);

  my $is_valid = $graphite->is_valid_key();

  my $counter = $graphite->get_invalid_key_counter();

  $graphite->check_and_bump_invalid_metric($key);

  my $is_blocked = $graphite->is_metric_blocked($key);

  $graphite->set_blocked_metrics_re($re);

  $graphite->DESTROY();

  # the following is actual only if C<use_global_storage> was set
  my %metrics      = %Graphite::Simple::bulk;
  my %avg_counters = %Graphite::Simple::avg_counters;

=head1 DESCRIPTION

  This package provides methods to collect metrics and send them to Graphite server over UDP socket.

=head2 $class->new(\%options)

It's a class constructor.
Takes a hash reference as argument.

=over

=item enabled

By default this option equals to 0.
The connection to Graphite host will be established if this value is true.

=item host

Sets the hostname or IPv4 address of Graphite server.
This option is mandatory if C<enabled> is true.

=item port

Sets the port number of Graphite server.
This option is mandatory if C<enabled> is true.

=item project

Sets a project's name (global prefix for all metrics).
This prefix will be applied to each metric before sending to server.

=item sender_name

Sets the method's name in format "package::method".

This method will be called from C<send_bulk_delegate> sub.
The hash reference with result metrics will be passed as arguments.

Be aware that the invocation of this method can lead to some performance penalties.

Optional.

=item block_metrics_re

The compiled regular expression.
If any metric matches, then it will be ignored and won't be stored in the resulted hash.

Optional.

=item use_global_storage

This flag is optional.
If flag is set then the package global hashes will be used to store collected data.

  my %metrics      = %Graphite::Simple::bulk;
  my %avg_counters = %Graphite::Simple::avg_counters;

Otherweise internal hashes will be used.

=back

=head2 $self->connect()

Establishes the connection to Graphite server if C<enabled> was set as true.

=head2 $self->disconnect()

Closes the connection.

=head2 $self->send_bulk_delegate()

Calculates the result metrics and passes them to specified method in C<sender_name>.

Previously stored keys will be used as average counters while getting the result. Example:

  $graphite->incr_bulk("avg,key", 4);
  $graphite->incr_bulk("avg,key", 8);

Here "avg.key" counter will be equal to 2. And the result value for "avg.key" is 6: (4 + 8) / 2

Be aware that the invocation of this method can lead to some performance penalties.

=head2 $self->send_bulk()

Calculates the result metrics and send them to Graphite server via direct connection.

Previously stored keys will be used as average counters while getting the result. Example:

  $graphite->incr_bulk("avg,key", 4);
  $graphite->incr_bulk("avg,key", 8);

Here "avg.key" counter will be equal to 2. And result value for "avg.key" is 6: (4 + 8) / 2

=head2 $self->get_average_counters()

Returns the hash reference with counters of average metrics.
Average metric is a metric started with "avg." string.

=head2 $self->get_metrics()

Returns the hash reference with result metrics.
Each metric started with "avg." string is divided by its counter from C<average_counter>.

=head2 $self->clear_bulk()

Clears all collected metrics;

=head2 $self->incr_bulk($key, $value = 1)

Increments metric C<$key> by value C<$value>.
If C<$value> is unspecified then 1 will be used.

=head2 $self->append_bulk($hash, $prefix = undef)

Increments metrics specified in C<$hash>.

The C<$hash> format:

$hash = {key1 => $value1, key2 => $value2, ...};

The second argument is optional and it specifies the common prefix.
If prefix doesn't contain a dot at the end, then it will be added automatically.

=head2 $self->is_valid_key($key)

Returns 1 if C<$key> is valid for usage as Graphite metric path.
Otherwise returns 0.

=head2 $self->get_invalid_key_counter()

Returns the amount of invalid metrics detected by C<is_valid_key> method.

=head2 $self->check_and_bump_invalid_metric($key)

If C<get_invalid_key_counter> returns a non-zero value, then this value will be written into passed C<$key>.
IF passed C<$key> is invalid, then invalid key counter will be bumped by 1.

=head2 $self->is_metric_blocked($key)

Returns 1 if C<$key> matches with reqular expression set with C<set_blocked_metrics_re>
or C<block_metrics_re>.

Otherwise returns 0.

=head2 $self->set_blocked_metrics_re($re = undef)

Sets regular expression to detect blocked metrics.
Such metrics won't be added to result.

If C<$re> is omitted or undefined then no any detection for blocked metrics will be used.

=head2 DESTROY

Destructor. Destroys object.

=head1 AUTHOR

Chernenko Dmitiry cdn@cpan.org

=cut
