File Coverage

blib/lib/Redis/OpenTracing.pm
Criterion Covered Total %
statement 66 66 100.0
branch 6 6 100.0
condition n/a
subroutine 15 16 93.7
pod 0 1 0.0
total 87 89 97.7


line stmt bran cond sub pod time code
1             package Redis::OpenTracing;
2              
3 6     6   2131311 use strict;
  6         55  
  6         191  
4 6     6   42 use warnings;
  6         14  
  6         180  
5              
6 6     6   1642 use syntax 'maybe';
  6         89315  
  6         37  
7              
8             our $VERSION = 'v0.3.0';
9              
10 6     6   17664 use Moo;
  6         28855  
  6         46  
11 6     6   9198 use Types::Standard qw/HashRef Maybe Object Str Value is_Str/;
  6         488176  
  6         76  
12              
13 6     6   20703 use OpenTracing::GlobalTracer;
  6         46380  
  6         68  
14 6     6   503 use Scalar::Util 'blessed';
  6         15  
  6         459  
15 6     6   46 use Carp qw/croak/ ;
  6         12  
  6         3254  
16              
17             has 'redis' => (
18             is => 'ro',
19             isa => Object, # beyond current scope to detect if it is a Redis like client
20             required => 1,
21             );
22              
23              
24              
25             has '_redis_client_class_name' => (
26             is => 'lazy',
27             isa => Str,
28             );
29              
30             sub _build__redis_client_class_name {
31 4     4   161 blessed( shift->redis )
32             };
33              
34              
35              
36             sub _operation_name {
37 13     13   37 my ( $self, $method_name ) = @_;
38            
39 13         205 return $self->_redis_client_class_name . '::' . $method_name;
40             }
41              
42              
43              
44             has 'tags' => (
45             is => 'ro',
46             isa => HashRef[Value],
47             default => sub { {} }, # an empty HashRef
48             );
49              
50              
51              
52             our $AUTOLOAD; # keep 'use strict' happy
53              
54             sub AUTOLOAD {
55 13     13   27043 my ($self) = @_;
56            
57 13         23 my $method_call = do { $_ = $AUTOLOAD; s/.*:://; $_ };
  13         29  
  13         76  
  13         54  
58 13         255 my $component_name = $self->_redis_client_class_name( );
59 13         257 my $db_statement = uc($method_call);
60 13         44 my $operation_name = $self->_operation_name( $method_call );
61            
62             my $method_wrap = sub {
63 14     14   822 my $self = shift;
64             my $scope = _global_tracer_start_active_span(
65             $operation_name,
66             tags => {
67             'component' => $component_name,
68            
69 14         28 %{ $self->tags( ) },
  14         107  
70            
71             'db.statement' => $db_statement,
72             'db.type' => 'redis',
73             'span.kind' => 'client',
74            
75             },
76             );
77            
78 14         29055 my $result;
79 14         65 my $wantarray = wantarray();
80            
81 14         29 my $ok = eval {
82 14 100       38 if ($wantarray) {
83 3         51 $result = [ $self->redis->$method_call(@_) ];
84             } else {
85 11         261 $result = $self->redis->$method_call(@_);
86             };
87 13         2049 1;
88             };
89 14         32 my $error = $@;
90            
91 14 100       36 if ( $ok ) {
92 13         189 $scope->close()
93             } else {
94 1         28 $scope->get_span()->add_tags(
95             generate_error_tags( $db_statement, $error )
96             );
97 1         575 $scope->close();
98 1         515 croak $error;
99             }
100            
101 13 100       3066 return $wantarray ? @$result : $result;
102 13         176 };
103            
104             # Save this method for future calls
105 6     6   78 no strict 'refs';
  6         23  
  6         1289  
106 13         68 *$AUTOLOAD = $method_wrap;
107            
108 13         41 goto $method_wrap;
109             }
110              
111              
112              
113             sub _global_tracer_start_active_span {
114 14     14   26 my $operation_name = shift;
115 14         33 my @args = @_;
116            
117 14         85 return OpenTracing::GlobalTracer->get_global_tracer()->start_active_span(
118             $operation_name,
119             @args,
120             );
121             }
122              
123              
124              
125             sub generate_error_tags {
126 1     1 0 82 my ( $db_statement, $error ) = @_;
127            
128 1         3 my $error_message = $error;
129 1         3 chomp $error_message;
130            
131 1         3 my $error_kind = "REDIS_EXCEPTION";
132             # my $error_kind = sprintf("REDIS_EXCEPTION_%s",
133             # $db_statement,
134             # );
135             #
136             return (
137 1         30 'error' => 1,
138             'message' => $error_message,
139             'error.kind' => $error_kind,
140             );
141             }
142              
143              
144              
145       0     sub DESTROY { } # we don't want this to be dispatched
146              
147              
148              
149             1;