]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / jaeger-client-cpp / src / jaegertracing / Span.cpp
1 /*
2 * Copyright (c) 2017 Uber Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jaegertracing/Span.h"
18 #include "jaegertracing/Tracer.h"
19 #include "jaegertracing/baggage/BaggageSetter.h"
20 #include "jaegertracing/thrift-gen/jaeger_types.h"
21 #include <cassert>
22 #include <cstdint>
23 #include <istream>
24 #include <memory>
25 #include <opentracing/value.h>
26
27 namespace jaegertracing {
28 namespace {
29
30 struct SamplingPriorityVisitor {
31 using result_type = bool;
32
33 bool operator()(bool boolValue) const { return boolValue; }
34
35 bool operator()(double doubleValue) const { return doubleValue > 0; }
36
37 bool operator()(int64_t intValue) const { return intValue > 0; }
38
39 bool operator()(uint64_t uintValue) const { return uintValue > 0; }
40
41 bool operator()(const std::string& str) const
42 {
43 std::istringstream iss(str);
44 auto intValue = 0;
45 if (!(iss >> intValue)) {
46 return false;
47 }
48 return intValue > 0;
49 }
50
51 bool operator()(std::nullptr_t) const { return false; }
52
53 bool operator()(const char* str) const
54 {
55 return operator()(std::string(str));
56 }
57
58 template <typename OtherType>
59 bool operator()(OtherType) const
60 {
61 return false;
62 }
63 };
64
65 } // anonymous namespace
66
67 void Span::SetBaggageItem(opentracing::string_view restrictedKey,
68 opentracing::string_view value) noexcept
69 {
70 std::lock_guard<std::mutex> lock(_mutex);
71 const auto& baggageSetter = _tracer->baggageSetter();
72 auto baggage = _context.baggage();
73 baggageSetter.setBaggage(*this,
74 baggage,
75 restrictedKey,
76 value,
77 [this](std::vector<Tag>::const_iterator first,
78 std::vector<Tag>::const_iterator last) {
79 logFieldsNoLocking(SystemClock::now(), first, last);
80 });
81 _context = _context.withBaggage(baggage);
82 }
83
84 void Span::FinishWithOptions(
85 const opentracing::FinishSpanOptions& finishSpanOptions) noexcept
86 {
87 const auto finishTimeSteady =
88 (finishSpanOptions.finish_steady_timestamp == SteadyClock::time_point())
89 ? SteadyClock::now()
90 : finishSpanOptions.finish_steady_timestamp;
91 std::shared_ptr<const Tracer> tracer;
92 {
93
94 std::lock_guard<std::mutex> lock(_mutex);
95 if (isFinished()) {
96 // Already finished, so return immediately.
97 return;
98 }
99 _duration = finishTimeSteady - _startTimeSteady;
100 if (_duration <= SteadyClock::duration()) {
101 // Enforce minimum duration of 1 tick (1ns on Linux),
102 // so isFinished() returns true
103 _duration = SteadyClock::duration(1);
104 }
105
106 tracer = _tracer;
107
108 std::copy(finishSpanOptions.log_records.begin(),
109 finishSpanOptions.log_records.end(),
110 std::back_inserter(_logs));
111 }
112
113 // Call `reportSpan` even for non-sampled traces.
114 if (tracer) {
115 tracer->reportSpan(*this);
116 }
117 }
118
119 const opentracing::Tracer& Span::tracer() const noexcept
120 {
121 std::lock_guard<std::mutex> lock(_mutex);
122 if (_tracer) {
123 return *_tracer;
124 }
125 auto tracer = opentracing::Tracer::Global();
126 assert(tracer);
127 return *tracer;
128 }
129
130 std::string Span::serviceName() const noexcept
131 {
132 std::lock_guard<std::mutex> lock(_mutex);
133 return serviceNameNoLock();
134 }
135
136 std::string Span::serviceNameNoLock() const noexcept
137 {
138 if (!_tracer) {
139 return std::string();
140 }
141 return _tracer->serviceName();
142 }
143
144 void Span::setSamplingPriority(const opentracing::Value& value)
145 {
146 SamplingPriorityVisitor visitor;
147 const auto priority = opentracing::Value::visit(value, visitor);
148
149 std::lock_guard<std::mutex> lock(_mutex);
150 auto newFlags = _context.flags();
151 if (priority) {
152 newFlags |= static_cast<unsigned char>(SpanContext::Flag::kSampled) |
153 static_cast<unsigned char>(SpanContext::Flag::kDebug);
154 }
155 else {
156 newFlags &= ~static_cast<unsigned char>(SpanContext::Flag::kSampled);
157 }
158
159 _context = SpanContext(_context.traceID(),
160 _context.spanID(),
161 _context.parentID(),
162 newFlags,
163 _context.baggage(),
164 _context.debugID());
165 }
166
167 void Span::thrift(thrift::Span& span) const
168 {
169 std::lock_guard<std::mutex> lock(_mutex);
170 span.__set_traceIdHigh(_context.traceID().high());
171 span.__set_traceIdLow(_context.traceID().low());
172 span.__set_spanId(_context.spanID());
173 span.__set_parentSpanId(_context.parentID());
174 span.__set_operationName(_operationName);
175
176 std::vector<thrift::SpanRef> refs;
177 refs.reserve(_references.size());
178 std::transform(std::begin(_references),
179 std::end(_references),
180 std::back_inserter(refs),
181 [](const Reference& ref) {
182 thrift::SpanRef thriftRef;
183 ref.thrift(thriftRef);
184 return thriftRef;
185 });
186 span.__set_references(refs);
187
188 span.__set_flags(_context.flags());
189 span.__set_startTime(std::chrono::duration_cast<std::chrono::microseconds>(
190 _startTimeSystem.time_since_epoch())
191 .count());
192 span.__set_duration(
193 std::chrono::duration_cast<std::chrono::microseconds>(_duration)
194 .count());
195
196 std::vector<thrift::Tag> tags;
197 tags.reserve(_tags.size());
198 std::transform(std::begin(_tags),
199 std::end(_tags),
200 std::back_inserter(tags),
201 [](const Tag& tag) {
202 thrift::Tag thriftTag;
203 tag.thrift(thriftTag);
204 return thriftTag;
205 });
206 span.__set_tags(tags);
207
208 std::vector<thrift::Log> logs;
209 logs.reserve(_logs.size());
210 std::transform(std::begin(_logs),
211 std::end(_logs),
212 std::back_inserter(logs),
213 [](const LogRecord& log) {
214 thrift::Log thriftLog;
215 log.thrift(thriftLog);
216 return thriftLog;
217 });
218 span.__set_logs(logs);
219 }
220
221 } // namespace jaegertracing