File Coverage

blib/lib/OpenTelemetry/Propagator/Baggage.pm
Criterion Covered Total %
statement 69 71 97.1
branch 7 10 70.0
condition 8 12 66.6
subroutine 13 13 100.0
pod 0 3 0.0
total 97 109 88.9


line stmt bran cond sub pod time code
1 4     4   219725 use Object::Pad;
  4         15309  
  4         29  
2             # ABSTRACT: Propagate context using the W3C Baggage format
3              
4             package OpenTelemetry::Propagator::Baggage;
5              
6             our $VERSION = '0.033';
7              
8 1     1   811 class OpenTelemetry::Propagator::Baggage :does(OpenTelemetry::Propagator) {
  1         3  
  1         109  
9 4     4   2426 use OpenTelemetry;
  4         13  
  4         44  
10 4     4   1362 use Feature::Compat::Try;
  4         10  
  4         39  
11 4     4   960 use OpenTelemetry::Baggage;
  4         8  
  4         160  
12 4     4   24 use OpenTelemetry::Common ();
  4         7  
  4         89  
13 4     4   63 use OpenTelemetry::Context;
  4         10  
  4         146  
14 4     4   24 use OpenTelemetry::Propagator::TextMap;
  4         8  
  4         153  
15 4     4   2225 use URL::Encode qw( url_decode_utf8 url_encode_utf8 );
  4         7622  
  4         344  
16              
17 4     4   32 use isa 'OpenTelemetry::X';
  4         8  
  4         37  
18              
19             my $KEY = 'baggage';
20             my $MAX_ENTRIES = 180;
21             my $MAX_ENTRY_LENGTH = 4096;
22             my $MAX_TOTAL_LENGTH = 8192;
23              
24             my $logger = OpenTelemetry::Common::internal_logger;
25              
26             method $encode (%baggage) {
27             my $encoded = '';
28             my $total = 0;
29              
30             for my $key ( keys %baggage ) {
31             last if $total > $MAX_ENTRIES;
32              
33             next unless $baggage{$key};
34             my $entry = join '=',
35             url_encode_utf8($key),
36             url_encode_utf8( $baggage{$key}->value );
37              
38             my $length = length $entry;
39             next unless $length < $MAX_ENTRY_LENGTH
40             && $length + length($encoded) < $MAX_TOTAL_LENGTH;
41              
42             $encoded .= ',' if $encoded;
43             $encoded .= $entry;
44              
45             if ( my $meta = $baggage{$key}->meta ) {
46             $encoded .= ";$meta";
47             }
48              
49             $total++;
50             }
51              
52             $encoded;
53             }
54              
55             method inject (
56 8         33 $carrier,
  8         17  
57 8         22 $context = undef,
58             $setter = undef
59 8     8 0 485 ) {
  8         19  
  8         16  
60 8   66     53 $context //= OpenTelemetry::Context->current;
61 8   66     61 $setter //= OpenTelemetry::Propagator::TextMap::SETTER;
62              
63 8         21 try {
64 8         81 my %baggage = OpenTelemetry::Baggage->all($context);
65 8 100       164 return $self unless %baggage;
66              
67 5         45 my $encoded = $self->$encode(%baggage);
68 5 50       30 $setter->( $carrier, $KEY, $encoded ) if $encoded;
69             }
70             catch($e) {
71 1 50       18 if ( isa_OpenTelemetry_X $e ) { $logger->warn($e->get_message) }
  0         0  
72             else {
73 1         9 OpenTelemetry->handle_error(
74             exception => $e,
75             message => 'Error while injecting baggage',
76             );
77             }
78             }
79              
80 5         140 return $self;
81             }
82              
83             method extract (
84 6         31 $carrier,
  6         12  
85 6         13 $context = undef,
86             $getter = undef
87 6     6 0 1740 ) {
  6         12  
  6         10  
88 6   66     76 $context //= OpenTelemetry::Context->current;
89 6   66     89 $getter //= OpenTelemetry::Propagator::TextMap::GETTER;
90              
91 6         18 try {
92 6 100       20 my $header = $carrier->$getter($KEY) or return $context;
93              
94 2         18 my $builder = OpenTelemetry::Baggage->builder;
95              
96 2         16 for ( split ',', $header =~ s/\s//gr ) {
97 2         12 my ( $kv, $meta ) = split ';', $_, 2;
98 2         22 my ( $key, $value ) = map url_decode_utf8($_), split '=', $kv, 2;
99 2         11 $builder->set( $key, $value, $meta );
100             }
101              
102 2         12 $builder->build($context);
103             }
104             catch($e) {
105 1 50       17 if ( isa_OpenTelemetry_X $e ) { $logger->warn($e->get_message) }
  0         0  
106             else {
107 1         7 OpenTelemetry->handle_error(
108             exception => $e,
109             message => 'Error while extracting baggage',
110             );
111             }
112              
113 1         10 return $context;
114             }
115             }
116              
117 3     3 0 12 method keys () { $KEY }
  3         10  
  3         6  
  3         24  
118             }