# You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # # (C) Paul Evans, 2020 -- leonerd@leonerd.org.uk package Metrics::Any::Adapter::Tee 0.10; use v5.14; use warnings; =head1 NAME C - send metrics to multiple adapters =head1 SYNOPSIS use Metrics::Any::Adapter 'Tee', "Prometheus", [ "File", path => "metrics.log" ], "Statsd"; =head1 DESCRIPTION This L adapter type acts as a container for multiple other adapters, allowing an application to report its metrics via multiple different mechanisms at the same time. =head1 ARGUMENTS Each value passed in the import list should either be an adapter type string or an array reference containing the name and additional arguments. Adapters specified by string are split in the same way as L splits the C environment variable; namely by parsing optional arguments after a colon, separated by commas or equals signs. E.g. "File:path=metrics.log" would be equivalent to the version given in the synopsis above. =cut sub new { my $class = shift; my @adapters; foreach ( @_ ) { # Adapters are probably specified by ARRAYref my ( $type, @args ) = ref $_ eq "ARRAY" ? @$_ : Metrics::Any::Adapter->split_type_string( $_ ); push @adapters, Metrics::Any::Adapter->class_for_type( $type )->new( @args ); } return bless { adapters => \@adapters, }, $class; } # Distribute each method call across all the adapters foreach my $method (qw( make_counter inc_counter_by make_distribution report_distribution make_gauge inc_gauge_by set_gauge make_timer report_timer )) { my $code = sub { my $self = shift; my @e; foreach my $adapter ( @{ $self->{adapters} } ) { defined eval { $adapter->$method( @_ ); 1 } or push @e, $@; } die $e[0] if @e; }; no strict 'refs'; *$method = $code; } =head1 AUTHOR Paul Evans =cut 0x55AA;