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 List::Util qw/ first /;
use Plack::Util;
use Plack::Util::Accessor
    qw/ client sample_rate histogram increment set_add catch_errors /;
use Ref::Util qw/ is_coderef /;
use Time::HiRes;
use Try::Tiny;

use experimental qw/ postderef signatures /;

our $VERSION = 'v0.8.2';

# 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   /],
          )
        {
            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;
            $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);
                        }
                    };

                }
            );
        }
    }

    if (my $attr = first { !is_coderef($self->$_) } qw/ histogram increment set_add /) {
        die "$attr is not a coderef";
    }

    if ( my $catch = $self->catch_errors ) {

        unless ( is_coderef($catch) ) {

            $self->catch_errors(
                sub( $env, $error ) {
                    if ( my $logger = $env->{'psgix.logger'} ) {
                        $logger->( { level => 'error', message => $error } );
                    }



( run in 1.066 second using v1.01-cache-2.11-cpan-39bf76dae61 )