File Coverage

blib/lib/Starch/Plugin/Net/Statsd/Store.pm
Criterion Covered Total %
statement 30 30 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 39 39 100.0


line stmt bran cond sub pod time code
1             package Starch::Plugin::Net::Statsd::Store;
2              
3             our $VERSION = '0.04';
4              
5 1     1   516 use Net::Statsd;
  1         3  
  1         40  
6 1     1   7 use Types::Common::String -types;
  1         2  
  1         8  
7 1     1   2315 use Time::HiRes qw( gettimeofday tv_interval );
  1         1369  
  1         5  
8 1     1   195 use Try::Tiny;
  1         2  
  1         81  
9              
10 1     1   10 use Moo::Role;
  1         2  
  1         7  
11 1     1   415 use strictures 2;
  1         6  
  1         36  
12 1     1   172 use namespace::clean;
  1         2  
  1         16  
13              
14             with qw(
15             Starch::Plugin::ForStore
16             );
17              
18             has statsd_path => (
19             is => 'lazy',
20             isa => NonEmptySimpleStr,
21             );
22             sub _build_statsd_path {
23 4     4   59 my ($self) = @_;
24 4         24 my $path = $self->short_store_class_name();
25              
26             # Path sanitization stolen, and slightly modified, from the statsd source.
27 4         166 $path =~ s{\s+}{_}g;
28 4         14 $path =~ s{/}{-}g;
29 4         11 $path =~ s{::}{-}g;
30 4         13 $path =~ s{[^a-zA-Z_\-0-9\.]}{}g;
31              
32 4         72 return $path;
33             }
34              
35             has statsd_full_path => (
36             is => 'lazy',
37             isa => NonEmptySimpleStr,
38             );
39             sub _build_statsd_full_path {
40 6     6   87 my ($self) = @_;
41 6         146 return $self->manager->statsd_root_path() . '.' . $self->statsd_path();
42             }
43              
44             foreach my $method (qw( set get remove )) {
45             around $method => sub{
46             my ($orig, $self, @args) = @_;
47              
48             local $Carp::Internal{ (__PACKAGE__) } = 1;
49              
50             return $self->$orig( @args ) if $self->isa('Starch::Store::Layered');
51              
52             my $path = $self->statsd_full_path() . '.' . $method;
53              
54             my $start = [gettimeofday];
55              
56             my ($errored, $error);
57             my $data = try { $self->$orig( @args ) }
58             catch { ($errored, $error) = (1, $_) };
59              
60             my $end = [gettimeofday];
61              
62             if ($errored) {
63             $path .= '-error';
64             }
65             elsif ($method eq 'get') {
66             $path .= '-' . ($data ? 'hit' : 'miss');
67             }
68              
69             my $host = $self->manager->statsd_host();
70             local $Net::Statsd::HOST = $host if defined $host;
71              
72             my $port = $self->manager->statsd_port();
73             local $Net::Statsd::PORT = $port if defined $port;
74              
75             Net::Statsd::timing(
76             $path,
77             tv_interval($start, $end) * 1000,
78             $self->manager->statsd_sample_rate(),
79             );
80              
81             die $error if $errored;
82              
83             return if $method ne 'get';
84             return $data;
85             };
86             }
87              
88             1;