File Coverage

blib/lib/OpenTracing/Span.pm
Criterion Covered Total %
statement 44 66 66.6
branch 5 6 83.3
condition 11 38 28.9
subroutine 17 28 60.7
pod 20 21 95.2
total 97 159 61.0


line stmt bran cond sub pod time code
1             package OpenTracing::Span;
2              
3 4     4   79445 use strict;
  4         15  
  4         126  
4 4     4   21 use warnings;
  4         6  
  4         194  
5              
6             our $VERSION = '1.006'; # VERSION
7             our $AUTHORITY = 'cpan:TEAM'; # AUTHORITY
8              
9 4     4   459 use parent qw(OpenTracing::Common);
  4         304  
  4         29  
10              
11 4     4   224 no indirect;
  4         7  
  4         18  
12 4     4   208 use utf8;
  4         9  
  4         15  
13              
14             =encoding utf8
15              
16             =head1 NAME
17              
18             OpenTracing::Span - represents an operation or parent operation
19              
20             =head1 DESCRIPTION
21              
22             The reference definition for a span is a good starting point for understanding these:
23              
24             L
25              
26             =cut
27              
28 4     4   2883 use Time::HiRes ();
  4         5753  
  4         172  
29 4     4   2349 use Bytes::Random::Secure qw(random_bytes_hex);
  4         42745  
  4         5005  
30              
31             =head2 new
32              
33             Instantiates a new span. Rarely called directly - you'd want to let the L take
34             care of this for you.
35              
36             Takes the following named parameters:
37              
38             =over 4
39              
40             =item * C - an L for a parent instance (optional)
41              
42             =item * C - the span ID for the parent (optional)
43              
44             =item * C - the current trace ID (optional)
45              
46             =item * C - what to use for this span name
47              
48             =back
49              
50             =cut
51              
52             sub new {
53 206     206 1 5000 my ($class, %args) = @_;
54 206   66     1288 $args{operation_name} //= (caller 1)[3];
55 206 100       475 if(my $parent = $args{parent}) {
56 1         2 $args{parent_id} = $parent->{id};
57 1         18 $args{trace_id} = $parent->{trace_id};
58             }
59              
60             # Alternatively reduce { $a * 1_000_000 + $b } Time::HiRes::gettimeofday(),
61             # but the time() version benchmarks to ~3x faster
62 206   33     877 $args{start_time} //= int(Time::HiRes::time() * 1_000_000);
63 206         489 bless \%args, $class
64             }
65              
66             =head2 trace_id
67              
68             The trace ID for this span. Multiple spans are grouped under a single trace.
69              
70             =cut
71              
72 106   66 106 1 6682 sub trace_id { shift->{trace_id} //= random_bytes_hex(16) }
73              
74             =head2 id
75              
76             The span ID. This should be unique.
77              
78             =cut
79              
80 105   66 105 1 8098 sub id { shift->{id} //= random_bytes_hex(8) }
81              
82             =head2 parent_id
83              
84             Parent span ID. 0 if there isn't one.
85              
86             =cut
87              
88 1   50 1 1 9 sub parent_id { shift->{parent_id} //= '0' x 8; }
89              
90             =head2 flags
91              
92             Any flags relating to this span.
93              
94             =cut
95              
96 0   0 0 1 0 sub flags { shift->{flags} // 0 }
97              
98             =head2 start_time
99              
100             Exact time this span started, in microseconds.
101              
102             =cut
103              
104 1   33 1 1 24 sub start_time { shift->{start_time} //= int(Time::HiRes::time() * 1_000_000) }
105              
106             =head2 start_time
107              
108             Exact time this span finished, in microseconds.
109              
110             Returns C if the span is not yet finished.
111              
112             =cut
113              
114 1     1 0 4 sub finish_time { shift->{finish_time} }
115              
116             =head2 duration
117              
118             Total duration of this span, including any nested spans.
119              
120             =cut
121              
122             sub duration {
123 3     3 1 8 my ($self) = @_;
124 3 100       20 return undef unless defined $self->{finish_time};
125 1   33     7 $self->{duration} //= $self->finish_time - $self->start_time;
126             }
127              
128             =head2 operation_name
129              
130             The operation that this span represents.
131              
132             =cut
133              
134 0     0 1 0 sub operation_name { shift->{operation_name} }
135              
136             =head2 tags
137              
138             The tags relating to this span.
139              
140             =cut
141              
142 0     0 1 0 sub tags { shift->{tags} }
143              
144             =head2 tag_list
145              
146             A list of tags as L instances.
147              
148             =cut
149              
150             sub tag_list {
151 0   0 0 1 0 my $tags = shift->{tags} //= {};
152 0         0 map { OpenTracing::Tag->new(key => $_, value => $tags->{$_}) } sort keys %$tags;
  0         0  
153             }
154              
155             =head2 logs
156              
157             The arrayref of log entries for this span, as L instances.
158              
159             =cut
160              
161 0     0 1 0 sub logs { shift->{logs} }
162              
163             =head2 log_list
164              
165             A list of log entries for this span, as L instances.
166              
167             =cut
168              
169             sub log_list {
170 0   0 0 1 0 (shift->{logs} //= [])->@*
171             }
172              
173             =head2 log
174              
175             Records a single log message.
176              
177             =cut
178              
179             sub log : method {
180 0     0 1 0 my ($self, $message, %args) = @_;
181 0         0 $args{message} = $message;
182 0   0     0 my $timestamp = delete($args{timestamp}) // int(Time::HiRes::time() * 1_000_000);
183 0   0     0 push +($self->{logs} //= [])->@*, my $log = OpenTracing::Log->new(
184             tags => \%args,
185             timestamp => $timestamp
186             );
187 0         0 $log;
188             }
189              
190             =head2 tag
191              
192             Applies key/value tags to this span.
193              
194             The L
195             may be of interest here.
196              
197             Example usage:
198              
199             $span->tag(
200             'http.status_code' => 200,
201             'http.url' => 'https://localhost/xxx',
202             'http.method' => 'GET'
203             );
204              
205             =cut
206              
207             sub tag : method {
208 0     0 1 0 my ($self, %args) = @_;
209 0         0 @{$self->{tags}}{keys %args} = values %args;
  0         0  
210 0         0 return $self;
211             }
212              
213             =head2 references
214              
215             The references relating to this span.
216              
217             =cut
218              
219 0     0 1 0 sub references { shift->{references} }
220              
221             =head2 reference_list
222              
223             A list of reference entries for this span, as L instances.
224              
225             =cut
226              
227             sub reference_list {
228 0   0 0 1 0 (shift->{references} //= [])->@*
229             }
230              
231              
232             =head2 reference
233              
234             Records a reference.
235              
236             =cut
237              
238             sub reference : method {
239 0     0 1 0 my ($self, %args) = @_;
240 0   0     0 push +($self->{references} //= [])->@*, my $reference = OpenTracing::Reference->new(%args);
241 0         0 $reference;
242             }
243              
244             =head2 tracer
245              
246             Returns the L for this span.
247              
248             =cut
249              
250 5     5 1 22 sub tracer { shift->{tracer} }
251              
252             =head2 is_finished
253              
254             Returns true if this span is finished (has a L), otherwise false.
255              
256             =cut
257              
258 9     9 1 37 sub is_finished { defined shift->{finish_time} }
259              
260             =head2 finish
261              
262             Mark this span as finished (populating the L field).
263              
264             =cut
265              
266             sub finish {
267 4     4 1 10 my ($self, $ts) = @_;
268 4 50       10 unless($self->is_finished) {
269 4   33     34 $ts //= int(Time::HiRes::time * 1_000_000);
270 4         7 $self->{finish_time} = $ts;
271 4         11 $self->tracer->finish_span($self);
272             }
273             $self
274 4         11 }
275              
276             1;
277              
278             __END__