/proc/self/cwd/source/extensions/tracers/zipkin/tracer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/extensions/tracers/zipkin/tracer.h" |
2 | | |
3 | | #include <chrono> |
4 | | |
5 | | #include "source/common/common/utility.h" |
6 | | #include "source/common/tracing/http_tracer_impl.h" |
7 | | #include "source/extensions/tracers/zipkin/util.h" |
8 | | #include "source/extensions/tracers/zipkin/zipkin_core_constants.h" |
9 | | |
10 | | namespace Envoy { |
11 | | namespace Extensions { |
12 | | namespace Tracers { |
13 | | namespace Zipkin { |
14 | | |
15 | | SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span_name, |
16 | 0 | SystemTime timestamp) { |
17 | | // Build the endpoint |
18 | 0 | Endpoint ep(service_name_, address_); |
19 | | |
20 | | // Build the CS annotation |
21 | 0 | Annotation cs; |
22 | 0 | cs.setEndpoint(std::move(ep)); |
23 | 0 | if (split_spans_for_request_) { |
24 | | // No previous context then this must be span created for downstream request. Server span will |
25 | | // be created for downstream request when split_spans_for_request is set to true |
26 | 0 | cs.setValue(SERVER_RECV); |
27 | 0 | } else { |
28 | 0 | cs.setValue(config.operationName() == Tracing::OperationName::Egress ? CLIENT_SEND |
29 | 0 | : SERVER_RECV); |
30 | 0 | } |
31 | | // Create an all-new span, with no parent id |
32 | 0 | SpanPtr span_ptr = std::make_unique<Span>(time_source_); |
33 | 0 | span_ptr->setName(span_name); |
34 | 0 | uint64_t random_number = random_generator_.random(); |
35 | 0 | span_ptr->setId(random_number); |
36 | 0 | span_ptr->setTraceId(random_number); |
37 | 0 | if (trace_id_128bit_) { |
38 | 0 | span_ptr->setTraceIdHigh(random_generator_.random()); |
39 | 0 | } |
40 | 0 | int64_t start_time_micro = std::chrono::duration_cast<std::chrono::microseconds>( |
41 | 0 | time_source_.monotonicTime().time_since_epoch()) |
42 | 0 | .count(); |
43 | 0 | span_ptr->setStartTime(start_time_micro); |
44 | | |
45 | | // Set the timestamp globally for the span and also for the CS annotation |
46 | 0 | uint64_t timestamp_micro = |
47 | 0 | std::chrono::duration_cast<std::chrono::microseconds>(timestamp.time_since_epoch()).count(); |
48 | 0 | cs.setTimestamp(timestamp_micro); |
49 | 0 | span_ptr->setTimestamp(timestamp_micro); |
50 | | |
51 | | // Add CS annotation to the span |
52 | 0 | span_ptr->addAnnotation(std::move(cs)); |
53 | |
|
54 | 0 | span_ptr->setTracer(this); |
55 | |
|
56 | 0 | return span_ptr; |
57 | 0 | } |
58 | | |
59 | | SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span_name, |
60 | 0 | SystemTime timestamp, const SpanContext& previous_context) { |
61 | 0 | SpanPtr span_ptr = std::make_unique<Span>(time_source_); |
62 | 0 | Annotation annotation; |
63 | 0 | uint64_t timestamp_micro; |
64 | |
|
65 | 0 | timestamp_micro = |
66 | 0 | std::chrono::duration_cast<std::chrono::microseconds>(timestamp.time_since_epoch()).count(); |
67 | |
|
68 | 0 | span_ptr->setName(span_name); |
69 | | |
70 | | // Set the span's kind (client or server) |
71 | 0 | if (split_spans_for_request_) { |
72 | | // If the previous context is an inner context then this span must be a span created for an |
73 | | // upstream request. A client span will be created for an upstream request. |
74 | 0 | if (previous_context.innerContext()) { |
75 | 0 | annotation.setValue(CLIENT_SEND); |
76 | 0 | } else { |
77 | 0 | annotation.setValue(SERVER_RECV); |
78 | 0 | } |
79 | 0 | } else { |
80 | 0 | if (config.operationName() == Tracing::OperationName::Egress) { |
81 | 0 | annotation.setValue(CLIENT_SEND); |
82 | 0 | } else { |
83 | 0 | annotation.setValue(SERVER_RECV); |
84 | 0 | } |
85 | 0 | } |
86 | | |
87 | | // Set the span's id and parent id |
88 | 0 | if (annotation.value() == CLIENT_SEND || !shared_span_context_) { |
89 | | // We need to create a new span that is a child of the previous span; no shared context |
90 | | |
91 | | // Create a new span id |
92 | 0 | uint64_t random_number = random_generator_.random(); |
93 | 0 | span_ptr->setId(random_number); |
94 | | |
95 | | // Set the parent id to the id of the previous span |
96 | 0 | span_ptr->setParentId(previous_context.id()); |
97 | | |
98 | | // Set the timestamp globally for the span |
99 | 0 | span_ptr->setTimestamp(timestamp_micro); |
100 | 0 | } else if (annotation.value() == SERVER_RECV) { |
101 | | // We need to create a new span that will share context with the previous span |
102 | | |
103 | | // Initialize the shared context for the new span |
104 | 0 | span_ptr->setId(previous_context.id()); |
105 | 0 | if (previous_context.parentId()) { |
106 | 0 | span_ptr->setParentId(previous_context.parentId()); |
107 | 0 | } |
108 | 0 | } else { |
109 | 0 | return span_ptr; // return an empty span |
110 | 0 | } |
111 | | |
112 | | // Build the endpoint |
113 | 0 | Endpoint ep(service_name_, address_); |
114 | | |
115 | | // Add the newly-created annotation to the span |
116 | 0 | annotation.setEndpoint(std::move(ep)); |
117 | 0 | annotation.setTimestamp(timestamp_micro); |
118 | 0 | span_ptr->addAnnotation(std::move(annotation)); |
119 | | |
120 | | // Keep the same trace id |
121 | 0 | span_ptr->setTraceId(previous_context.traceId()); |
122 | 0 | if (previous_context.is128BitTraceId()) { |
123 | 0 | span_ptr->setTraceIdHigh(previous_context.traceIdHigh()); |
124 | 0 | } |
125 | | |
126 | | // Keep the same sampled flag |
127 | 0 | span_ptr->setSampled(previous_context.sampled()); |
128 | |
|
129 | 0 | int64_t start_time_micro = std::chrono::duration_cast<std::chrono::microseconds>( |
130 | 0 | time_source_.monotonicTime().time_since_epoch()) |
131 | 0 | .count(); |
132 | 0 | span_ptr->setStartTime(start_time_micro); |
133 | |
|
134 | 0 | span_ptr->setTracer(this); |
135 | |
|
136 | 0 | return span_ptr; |
137 | 0 | } |
138 | | |
139 | 0 | void Tracer::reportSpan(Span&& span) { |
140 | 0 | if (reporter_ && span.sampled()) { |
141 | 0 | reporter_->reportSpan(std::move(span)); |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | 0 | void Tracer::setReporter(ReporterPtr reporter) { reporter_ = std::move(reporter); } |
146 | | |
147 | | } // namespace Zipkin |
148 | | } // namespace Tracers |
149 | | } // namespace Extensions |
150 | | } // namespace Envoy |