File Coverage

blib/lib/OpenTracing/Span.pm
Criterion Covered Total %
statement 44 61 72.1
branch 5 6 83.3
condition 11 34 32.3
subroutine 17 25 68.0
pod 17 18 94.4
total 94 144 65.2


line stmt bran cond sub pod time code
1             package OpenTracing::Span;
2              
3 4     4   70974 use strict;
  4         15  
  4         105  
4 4     4   16 use warnings;
  4         6  
  4         172  
5              
6             our $VERSION = '1.003'; # VERSION
7             our $AUTHORITY = 'cpan:TEAM'; # AUTHORITY
8              
9 4     4   437 use parent qw(OpenTracing::Common);
  4         260  
  4         18  
10              
11 4     4   165 no indirect;
  4         5  
  4         25  
12 4     4   173 use utf8;
  4         6  
  4         25  
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   1925 use Time::HiRes ();
  4         4950  
  4         477  
29 4     4   1955 use Bytes::Random::Secure qw(random_bytes_hex);
  4         37359  
  4         3853  
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 4241 my ($class, %args) = @_;
54 206   66     1000 $args{operation_name} //= (caller 1)[3];
55 206 100       364 if(my $parent = $args{parent}) {
56 1         4 $args{parent_id} = $parent->id;
57 1         3 $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     678 $args{start_time} //= int(Time::HiRes::time() * 1_000_000);
63 206         416 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 5407 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 5483 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 10 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 11 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 6 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 9 my ($self) = @_;
124 3 100       30 return undef unless defined $self->{finish_time};
125 1   33     16 $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 tracer
214              
215             Returns the L for this span.
216              
217             =cut
218              
219 5     5 1 44 sub tracer { shift->{tracer} }
220              
221             =head2 is_finished
222              
223             Returns true if this span is finished (has a L), otherwise false.
224              
225             =cut
226              
227 9     9 1 44 sub is_finished { defined shift->{finish_time} }
228              
229             =head2 finish
230              
231             Mark this span as finished (populating the L field).
232              
233             =cut
234              
235             sub finish {
236 4     4 1 9 my ($self, $ts) = @_;
237 4 50       146 unless($self->is_finished) {
238 4   33     67 $ts //= int(Time::HiRes::time * 1_000_000);
239 4         9 $self->{finish_time} = $ts;
240 4         61 $self->tracer->finish_span($self);
241             }
242             $self
243 4         12 }
244              
245             1;
246              
247             __END__