File Coverage

blib/lib/Net/Statsd/Tiny.pm
Criterion Covered Total %
statement 62 68 91.1
branch 12 18 66.6
condition 4 6 66.6
subroutine 14 15 93.3
pod 4 5 80.0
total 96 112 85.7


line stmt bran cond sub pod time code
1             package Net::Statsd::Tiny;
2              
3             # ABSTRACT: A tiny StatsD client that supports multimetric packets
4              
5 24     24   11590656 use v5.10.1;
  24         96  
6              
7 24     24   192 use strict;
  24         48  
  24         1416  
8 24     24   168 use warnings;
  24         48  
  24         1824  
9              
10 24     24   168 use base qw/ Class::Accessor::Fast /;
  24         48  
  24         16104  
11              
12 24     24   95376 use IO::Socket 1.18 ();
  24         600  
  24         9960  
13              
14             our $VERSION = 'v0.3.7';
15              
16              
17             __PACKAGE__->mk_ro_accessors(
18             qw/ host port proto prefix
19             autoflush max_buffer_size _socket /
20             );
21              
22             sub new {
23 23     23 1 373412967 my ( $class, @args ) = @_;
24              
25 23         902 my %args;
26 23 50 33     3218 if ( ( @args == 1 ) && ( ref( $args[0] ) eq 'HASH' ) ) {
27 0         0 %args = %{ $args[0] };
  0         0  
28             }
29             else {
30 23         6880 %args = @args;
31             }
32              
33 23         1684 my %DEFAULTS = (
34             host => '127.0.0.1',
35             port => 8125,
36             proto => 'udp',
37             prefix => '',
38             autoflush => 1,
39             max_buffer_size => 512,
40             );
41              
42 23         1601 foreach my $attr ( keys %DEFAULTS ) {
43 138 50       1416 next if exists $args{$attr};
44 0         0 $args{$attr} = $DEFAULTS{$attr};
45             }
46              
47             $args{_socket} = IO::Socket::INET->new(
48             PeerAddr => $args{host},
49             PeerPort => $args{port},
50             Proto => $args{proto},
51 23 50       2051 ) or die "Failed to initialize socket: $!";
52              
53 23         26463 my $self = $class->SUPER::new( \%args );
54              
55 23         1952 $self->{_buffer} = '';
56              
57 23         246 return $self;
58             }
59              
60              
61             BEGIN {
62 24     24   144 my $class = __PACKAGE__;
63              
64 24         192 my %PROTOCOL = (
65             set_add => 's',
66             counter => 'c',
67             gauge => 'g',
68             histogram => 'h',
69             meter => 'm',
70             timing => 'ms',
71             );
72              
73 24         120 foreach my $name ( keys %PROTOCOL ) {
74              
75 24     24   216 no strict 'refs'; ## no critic (ProhibitNoStrict)
  24         24  
  24         5376  
76              
77 144         336 my $suffix = '|' . $PROTOCOL{$name};
78              
79 144         624 *{"${class}::${name}"} = sub {
80 27     27   17020785 my ( $self, $metric, $value, $rate ) = @_;
81 27 100 100     1302 if ( ( defined $rate ) && ( $rate < 1 ) ) {
82 4 100       309 $self->_record( $suffix . '|@' . $rate, $metric, $value )
83             if rand() < $rate;
84             }
85             else {
86 23         1134 $self->_record( $suffix, $metric, $value );
87             }
88 144         720 };
89              
90             }
91              
92             # Alises for other Net::Statsd::Client or Etsy::StatsD
93              
94             {
95 24     24   216 no strict 'refs'; ## no critic (ProhibitNoStrict)
  24         72  
  24         2472  
  24         72  
96              
97 24         48 *{"${class}::update"} = \&counter;
  24         120  
98 24         72 *{"${class}::timing_ms"} = \&timing;
  24         10584  
99              
100             }
101              
102             }
103              
104             sub increment {
105 4     4 1 4006101 my ( $self, $metric, $rate ) = @_;
106 4         129 $self->counter( $metric, 1, $rate );
107             }
108              
109             sub decrement {
110 2     2 1 2001899 my ( $self, $metric, $rate ) = @_;
111 2         17 $self->counter( $metric, -1, $rate );
112             }
113              
114             sub _record {
115 24     24   173 my ( $self, $suffix, $metric, $value ) = @_;
116              
117 24         7333 my $data = $self->prefix . $metric . ':' . $value . $suffix . "\n";
118              
119 24 100       1473 if ( $self->autoflush ) {
120 18         2507 send( $self->_socket, $data, 0 );
121 18         3126 return;
122             }
123              
124 6         206 my $avail = $self->max_buffer_size - length( $self->{_buffer} );
125 6 100       149 $self->flush if length($data) > $avail;
126              
127 6         62 $self->{_buffer} .= $data;
128             }
129              
130              
131              
132             sub flush {
133 2     2 1 15 my ($self) = @_;
134              
135 2 50       62 if ( length($self->{_buffer}) ) {
136 2         91 send( $self->_socket, $self->{_buffer}, 0 );
137 2         315 $self->{_buffer} = '';
138             }
139             }
140              
141             sub DEMOLISH {
142 0     0 0   my ( $self, $is_global ) = @_;
143              
144 0 0         return if $is_global;
145              
146 0           $self->flush;
147             }
148              
149              
150             1;
151              
152             __END__