Plack-Middleware-Statsd

 view release on metacpan or  search on metacpan

lib/Plack/Middleware/Statsd.pm  view on Meta::CPAN

package Plack::Middleware::Statsd;

# ABSTRACT: send statistics to statsd

# RECOMMEND PREREQ: Net::Statsd::Tiny v0.3.0
# RECOMMEND PREREQ: HTTP::Status 6.16
# RECOMMEND PREREQ: List::Util::XS
# RECOMMEND PREREQ: Ref::Util::XS

use v5.20;
use warnings;

use parent qw/ Plack::Middleware /;

use Digest::SHA 5.96 qw/ hmac_sha256_base64 /;
use List::Util qw/ first /;
use Plack::Util;
use Plack::Util::Accessor
    qw/ client sample_rate histogram increment set_add secure_set_add secure_set_key catch_errors /;
use Ref::Util qw/ is_coderef /;
use Scalar::Util qw/ weaken /;
use Time::HiRes;
use Try::Tiny;

use experimental qw/ postderef signatures /;

our $VERSION = 'v0.9.3';

# Note: You may be able to omit the client if there is a client
# defined in the environment hash at C<psgix.monitor.statsd>, and the
# L</histogram>, L</increment> and L</attributes> are set.  But that
# is a strange case and unsupported.

sub prepare_app($self) {

    if ( my $client = $self->client ) {
        foreach my $init (
            [qw/ histogram timing_ms timing /],
            [qw/ increment increment /],
            [qw/ set_add   set_add   /],
            [qw/ secure_set_add secure_set_add /],
          )
        {
            my ( $attr, @methods ) = $init->@*;
            next if defined $self->$attr;
            my $method = first { $client->can($_) } @methods;
            warn "No $attr method found for client " . ref($client)
                unless defined $method || $attr eq "secure_set_add";
            $self->$attr(
                sub($env, @args) {
                    return unless defined $method;
                    try {
                        $client->$method( grep { defined $_ } @args );
                    }
                    catch {
                        my ($e) = $_;
                        if (my $logger = $env->{'psgix.logger'}) {
                            $logger->( { message => $e, level => 'error' } );
                        }
                        else {
                            $env->{'psgi.errors'}->print($e);
                        }
                    };

                }
            );
        }

        unless ( $client->can("secure_set_add") ) {
            if ( my $key = $self->secure_set_key ) {
                $self->secure_set_add(
                    sub( $env, $metric, $string ) {
                        my $obscure = hmac_sha256_base64( $string, $key );
                        $self->set_add->( $env, $metric, $obscure );
                    }
                );
            }
        }

    }



( run in 0.964 second using v1.01-cache-2.11-cpan-6aa56a78535 )