File Coverage

blib/lib/OpenTracing/Implementation/DataDog/Tracer.pm
Criterion Covered Total %
statement 39 39 100.0
branch n/a
condition n/a
subroutine 13 13 100.0
pod n/a
total 52 52 100.0


line stmt bran cond sub pod time code
1             package OpenTracing::Implementation::DataDog::Tracer;
2              
3 8     8   1190406 use strict;
  8         65  
  8         237  
4 8     8   43 use warnings;
  8         21  
  8         356  
5              
6              
7             our $VERSION = 'v0.47.0';
8              
9             =head1 NAME
10              
11             OpenTracing::Implementation::DataDog::Tracer - Keep track of traces
12              
13             =head1 SYNOPSIS
14              
15             use aliased 'OpenTracing::Implementation::DataDog::Tracer';
16             use aliased 'OpenTracing::Implementation::DataDog::Client';
17             use aliased 'OpenTracing::Implementation::DataDog::ScopeManager';
18            
19             my $TRACER = Tracer->new(
20             client => Client->new(),
21             );
22              
23             and later
24              
25             sub foo {
26            
27             my $scope = $TRACER->start_active_span( 'Operation Name' => %options );
28            
29             ...
30            
31             $scope->close;
32            
33             return $foo
34             }
35              
36             =cut
37              
38 8     8   2540 use syntax 'maybe';
  8         160994  
  8         40  
39              
40 8     8   27154 use Moo;
  8         40009  
  8         52  
41 8     8   13952 use MooX::Should;
  8         91487  
  8         69  
42              
43             with 'OpenTracing::Role::Tracer';
44              
45 8     8   1987 use aliased 'OpenTracing::Implementation::DataDog::Client';
  8         3321  
  8         63  
46 8     8   1206 use aliased 'OpenTracing::Implementation::DataDog::HTTPPropagator';
  8         26  
  8         59  
47 8     8   710 use aliased 'OpenTracing::Implementation::DataDog::ScopeManager';
  8         19  
  8         49  
48 8     8   1140 use aliased 'OpenTracing::Implementation::DataDog::Span';
  8         21  
  8         64  
49 8     8   1124 use aliased 'OpenTracing::Implementation::DataDog::SpanContext';
  8         25  
  8         71  
50              
51 8     8   7115 use Hash::Merge;
  8         39682  
  8         422  
52 8     8   85 use Ref::Util qw/is_plain_hashref/;
  8         29  
  8         515  
53 8     8   71 use Types::Standard qw/Object Str/;
  8         21  
  8         85  
54              
55              
56              
57             =head1 DESCRIPTION
58              
59             This is a L<OpenTracing SpanContext|OpenTracing::Interface::SpanContext>
60             compliant implementation with DataDog specific extentions
61              
62             =cut
63              
64              
65              
66             =head1 EXTENDED ATTRIBUTES
67              
68             =cut
69              
70              
71              
72             =head2 C<scope_manager>
73              
74             A L<OpenTracing::Types::ScopeManger> that now defaults to a
75             L<DataDog::ScopeManger|OpenTracing::Implementation::DataDog::ScopeManager>
76              
77             =cut
78              
79             has '+scope_manager' => (
80             default => sub { ScopeManager->new },
81             );
82              
83              
84              
85             =head1 DATADOG SPECIFIC ATTRIBUTES
86              
87             =cut
88              
89              
90              
91             =head2 C<client>
92              
93             A client that has a C<send_span> method that will get called on a `on_finish`.
94              
95             See L<DataDog::Client|OpenTracing::Implementation::DataDog::Client> for more.
96              
97             It also accepts a plain hash refference with key-value pairs suitable to
98             construct a client object.
99              
100             =cut
101              
102             has client => (
103             is => 'lazy',
104             should => Object,
105             handles => [qw/send_span/],
106             coerce
107             => sub { is_plain_hashref $_[0] ? Client->new( %{$_[0]} ) : $_[0] },
108             default => sub { {} }, # XXX this does not return an Object !!!
109             );
110              
111              
112              
113             has default_resource_name => (
114             is => 'ro',
115             should => Str,
116             predicate => 1,
117             );
118              
119              
120              
121             has default_service_name => (
122             is => 'ro',
123             should => Str,
124             predicate => 1,
125             );
126              
127              
128              
129             has default_service_type => (
130             is => 'ro',
131             should => Str,
132             predicate => 1,
133             );
134              
135              
136              
137             has default_environment => (
138             is => 'ro',
139             should => Str,
140             predicate => 1,
141             );
142              
143              
144              
145             has default_hostname => (
146             is => 'ro',
147             should => Str,
148             predicate => 1,
149             );
150              
151              
152              
153             has default_version => (
154             is => 'ro',
155             should => Str,
156             predicate => 1,
157             );
158              
159             has '_http_propagator' => (
160             is => 'ro',
161             default => sub { HTTPPropagator->new },
162             );
163              
164              
165              
166             sub build_span {
167             my $self = shift;
168             my %opts = @_;
169            
170             my $span = Span->new(
171            
172             operation_name => $opts{ operation_name },
173            
174             maybe
175             child_of => $opts{ child_of },
176            
177             maybe
178             start_time => $opts{ start_time },
179            
180             maybe
181             tags => $opts{ tags },
182            
183             context => $opts{ context },
184            
185             on_finish => sub {
186             my $span = shift;
187             $self->send_span( $span )
188             },
189            
190             );
191            
192             return $span
193             }
194              
195              
196              
197             sub build_context {
198             my $self = shift;
199             my %opts = @_;
200            
201             my $resource_name = delete $opts{ resource_name }
202             || $self->default_resource_name;
203            
204             my $service_name = delete $opts{ service_name }
205             || $self->default_service_name;
206            
207             my $service_type = delete $opts{ service_type }
208             || $self->default_service_type;
209            
210             my $environment = delete $opts{ environment }
211             || $self->default_environment;
212            
213             my $hostname = delete $opts{ hostname }
214             || $self->default_hostname;
215            
216             my $version = delete $opts{ version }
217             || $self->default_version;
218            
219             my $span_context = SpanContext->new(
220            
221             %opts,
222            
223             resource_name => $resource_name,
224            
225             maybe
226             service_name => $service_name,
227            
228             maybe
229             service_type => $service_type,
230            
231             maybe
232             environment => $environment,
233            
234             maybe
235             hostname => $hostname,
236            
237             maybe
238             version => $version,
239            
240             );
241            
242             return $span_context
243             }
244              
245              
246              
247             sub inject_context_into_array_reference { return $_[1] } # $carrier
248              
249              
250              
251             sub inject_context_into_hash_reference {
252             my $self = shift;
253             my $carrier = shift;
254             my $context = shift;
255            
256             return Hash::Merge->new('RIGHT_PRECEDENT')->merge(
257             $carrier,
258             {
259             opentracing_context => {
260             trace_id => $context->trace_id,
261             span_id => $context->span_id,
262             resource => $context->get_resource_name,
263             service => $context->get_service_name,
264             maybe
265             type => $context->get_service_type,
266             maybe
267             environment => $context->get_environment,
268             maybe
269             hostname => $context->get_hostname,
270             }
271            
272             }
273             )
274             }
275              
276              
277              
278             sub inject_context_into_http_headers {
279             my ($self, $carrier, $context) = @_;
280             $carrier = $carrier->clone;
281              
282             $self->_http_propagator->inject($carrier, $context);
283              
284             return $carrier;
285             }
286              
287             sub extract_context_from_array_reference { return undef }
288             sub extract_context_from_hash_reference { return undef }
289              
290             sub extract_context_from_http_headers {
291             my ($self, $carrier) = @_;
292             my ($trace_id, $span_id) = $self->_http_propagator->extract($carrier);
293             return unless defined $trace_id and defined $span_id;
294              
295             return $self->build_context()
296             ->with_trace_id($trace_id)
297             ->with_span_id($span_id);
298             }
299              
300             =head1 SEE ALSO
301              
302             =over
303              
304             =item L<OpenTracing::Implementation::DataDog>
305              
306             Sending traces to DataDog using Agent.
307              
308             =item L<OpenTracing::Role::Tracer>
309              
310             Role for OpenTracing Implementations.
311              
312             =back
313              
314              
315              
316             =head1 AUTHOR
317              
318             Theo van Hoesel <tvanhoesel@perceptyx.com>
319              
320              
321              
322             =head1 COPYRIGHT AND LICENSE
323              
324             'OpenTracing::Implementation::DataDog'
325             is Copyright (C) 2019 .. 2021, Perceptyx Inc
326              
327             This library is free software; you can redistribute it and/or modify it under
328             the terms of the Artistic License 2.0.
329              
330             This package is distributed in the hope that it will be useful, but it is
331             provided "as is" and without any express or implied warranties.
332              
333             For details, see the full text of the license in the file LICENSE.
334              
335              
336             =cut
337              
338             1;