File Coverage

blib/lib/Metrics/Any/Adapter/Tee.pm
Criterion Covered Total %
statement 22 22 100.0
branch 3 6 50.0
condition n/a
subroutine 5 5 100.0
pod 0 1 0.0
total 30 34 88.2


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 -- leonerd@leonerd.org.uk
5              
6             package Metrics::Any::Adapter::Tee 0.10;
7              
8 2     2   430 use v5.14;
  2         7  
9 2     2   9 use warnings;
  2         4  
  2         523  
10              
11             =head1 NAME
12              
13             C - send metrics to multiple adapters
14              
15             =head1 SYNOPSIS
16              
17             use Metrics::Any::Adapter 'Tee',
18             "Prometheus",
19             [ "File", path => "metrics.log" ],
20             "Statsd";
21              
22             =head1 DESCRIPTION
23              
24             This L adapter type acts as a container for multiple other
25             adapters, allowing an application to report its metrics via multiple different
26             mechanisms at the same time.
27              
28             =head1 ARGUMENTS
29              
30             Each value passed in the import list should either be an adapter type string
31             or an array reference containing the name and additional arguments.
32              
33             Adapters specified by string are split in the same way as
34             L splits the C environment
35             variable; namely by parsing optional arguments after a colon, separated by
36             commas or equals signs. E.g.
37              
38             "File:path=metrics.log"
39              
40             would be equivalent to the version given in the synopsis above.
41              
42             =cut
43              
44             sub new
45             {
46 1     1 0 2 my $class = shift;
47              
48 1         2 my @adapters;
49 1         2 foreach ( @_ ) {
50             # Adapters are probably specified by ARRAYref
51 2 50       28 my ( $type, @args ) = ref $_ eq "ARRAY" ? @$_ : Metrics::Any::Adapter->split_type_string( $_ );
52 2         8 push @adapters, Metrics::Any::Adapter->class_for_type( $type )->new( @args );
53             }
54              
55 1         14 return bless {
56             adapters => \@adapters,
57             }, $class;
58             }
59              
60             # Distribute each method call across all the adapters
61             foreach my $method (qw(
62             make_counter inc_counter_by
63             make_distribution report_distribution
64             make_gauge inc_gauge_by set_gauge
65             make_timer report_timer
66             )) {
67             my $code = sub {
68 8     8   14 my $self = shift;
69              
70 8         10 my @e;
71 8         40 foreach my $adapter ( @{ $self->{adapters} } ) {
  8         18  
72 16 50       21 defined eval { $adapter->$method( @_ ); 1 } or
  16         57  
  16         66  
73             push @e, $@;
74             }
75 8 50       32 die $e[0] if @e;
76             };
77              
78 2     2   16 no strict 'refs';
  2         4  
  2         116  
79             *$method = $code;
80             }
81              
82             =head1 AUTHOR
83              
84             Paul Evans
85              
86             =cut
87              
88             0x55AA;