File Coverage

blib/lib/Metrics/Any/Adapter/DogStatsd.pm
Criterion Covered Total %
statement 33 33 100.0
branch 4 6 66.6
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 44 48 91.6


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2020-2026 -- leonerd@leonerd.org.uk
5              
6             package Metrics::Any::Adapter::DogStatsd 0.04;
7              
8 2     2   332322 use v5.14;
  2         6  
9 2     2   47 use warnings;
  2         4  
  2         109  
10 2     2   9 use base qw( Metrics::Any::Adapter::Statsd );
  2         3  
  2         580  
11              
12 2     2   10 use Carp;
  2         4  
  2         910  
13              
14             # See also
15             # https://metacpan.org/release/DataDog-DogStatsd/source/lib/DataDog/DogStatsd.pm
16              
17             =head1 NAME
18              
19             C - a metrics reporting adapter for DogStatsd
20              
21             =head1 SYNOPSIS
22              
23             =for highlighter language=perl
24              
25             use Metrics::Any::Adapter 'DogStatsd';
26              
27             =head1 DESCRIPTION
28              
29             This extension of L supports the additional tag
30             reporting syntax defined by F to report labelled metrics.
31              
32             Additionally, distribution metrics are reported as native DogStatsd histograms
33             rather than the two-part count-and-sum implementation of plain statsd. Due to
34             limitations of the line-based protocol, certain characters are not allowed in
35             label names or values. Any C<:>, C<|>, C<,> or linefeeds are replaced by C<_>.
36              
37             =cut
38              
39             sub _tags
40             {
41 5     5   7 my ( $labels, $labelvalues ) = @_;
42              
43 5         6 my @tags;
44 5         9 foreach ( 0 .. $#$labels ) {
45 5         8 my $name = $labels->[$_];
46 5         6 my $value = $labelvalues->[$_];
47             # Replace disallowed characters with '_'
48 5         18 $_ =~ s/[:|,\n]/_/g for $name, $value;
49              
50 5         12 push @tags, "$name:$value";
51             }
52              
53 5 50       10 return "" unless @tags;
54 5         17 return "|#" . join( ",", @tags );
55             }
56              
57             sub send
58             {
59 5     5 0 7 my $self = shift;
60 5         9 my ( $stats, $labelnames, $labelvalues ) = @_;
61              
62 5         12 foreach my $name ( keys %$stats ) {
63 5         6 my $value = $stats->{$name};
64 5 100       12 my @values = ( ref $value ) ? @$value : ( $value );
65 5         13 $_ .= _tags( $labelnames, $labelvalues ) for @values;
66 5         10 $stats->{$name} = \@values
67             }
68              
69 5         12 $self->SUPER::send( $stats );
70             }
71              
72             # DogStatsd has a native "histogram" format; we'll use that
73             sub report_distribution
74             {
75 1     1 0 31 my $self = shift;
76 1         2 my ( $handle, $amount, @labelvalues ) = @_;
77              
78 1 50       3 my $meta = $self->{metrics}{$handle} or croak "No metric '$handle'";
79              
80 1         7 my $value = sprintf "%g|h", $amount;
81              
82 1         5 $self->send( { $meta->{name} => $value }, $meta->{labels}, \@labelvalues );
83             }
84              
85             *inc_distribution_by = \&report_distribution;
86              
87             =head1 AUTHOR
88              
89             Paul Evans
90              
91             =cut
92              
93             0x55AA;