2 * Copyright (c) 2017 Uber Technologies, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "jaegertracing/Span.h"
18 #include "jaegertracing/Tracer.h"
19 #include "jaegertracing/baggage/BaggageSetter.h"
20 #include "jaegertracing/thrift-gen/jaeger_types.h"
25 #include <opentracing/value.h>
27 namespace jaegertracing
{
30 struct SamplingPriorityVisitor
{
31 using result_type
= bool;
33 bool operator()(bool boolValue
) const { return boolValue
; }
35 bool operator()(double doubleValue
) const { return doubleValue
> 0; }
37 bool operator()(int64_t intValue
) const { return intValue
> 0; }
39 bool operator()(uint64_t uintValue
) const { return uintValue
> 0; }
41 bool operator()(const std::string
& str
) const
43 std::istringstream
iss(str
);
45 if (!(iss
>> intValue
)) {
51 bool operator()(std::nullptr_t
) const { return false; }
53 bool operator()(const char* str
) const
55 return operator()(std::string(str
));
58 template <typename OtherType
>
59 bool operator()(OtherType
) const
65 } // anonymous namespace
67 void Span::SetBaggageItem(opentracing::string_view restrictedKey
,
68 opentracing::string_view value
) noexcept
70 std::lock_guard
<std::mutex
> lock(_mutex
);
71 const auto& baggageSetter
= _tracer
->baggageSetter();
72 auto baggage
= _context
.baggage();
73 baggageSetter
.setBaggage(*this,
77 [this](std::vector
<Tag
>::const_iterator first
,
78 std::vector
<Tag
>::const_iterator last
) {
79 logFieldsNoLocking(SystemClock::now(), first
, last
);
81 _context
= _context
.withBaggage(baggage
);
84 void Span::FinishWithOptions(
85 const opentracing::FinishSpanOptions
& finishSpanOptions
) noexcept
87 const auto finishTimeSteady
=
88 (finishSpanOptions
.finish_steady_timestamp
== SteadyClock::time_point())
90 : finishSpanOptions
.finish_steady_timestamp
;
91 std::shared_ptr
<const Tracer
> tracer
;
94 std::lock_guard
<std::mutex
> lock(_mutex
);
96 // Already finished, so return immediately.
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);
108 std::copy(finishSpanOptions
.log_records
.begin(),
109 finishSpanOptions
.log_records
.end(),
110 std::back_inserter(_logs
));
113 // Call `reportSpan` even for non-sampled traces.
115 tracer
->reportSpan(*this);
119 const opentracing::Tracer
& Span::tracer() const noexcept
121 std::lock_guard
<std::mutex
> lock(_mutex
);
125 auto tracer
= opentracing::Tracer::Global();
130 std::string
Span::serviceName() const noexcept
132 std::lock_guard
<std::mutex
> lock(_mutex
);
133 return serviceNameNoLock();
136 std::string
Span::serviceNameNoLock() const noexcept
139 return std::string();
141 return _tracer
->serviceName();
144 void Span::setSamplingPriority(const opentracing::Value
& value
)
146 SamplingPriorityVisitor visitor
;
147 const auto priority
= opentracing::Value::visit(value
, visitor
);
149 std::lock_guard
<std::mutex
> lock(_mutex
);
150 auto newFlags
= _context
.flags();
152 newFlags
|= static_cast<unsigned char>(SpanContext::Flag::kSampled
) |
153 static_cast<unsigned char>(SpanContext::Flag::kDebug
);
156 newFlags
&= ~static_cast<unsigned char>(SpanContext::Flag::kSampled
);
159 _context
= SpanContext(_context
.traceID(),
167 void Span::thrift(thrift::Span
& span
) const
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
);
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
);
186 span
.__set_references(refs
);
188 span
.__set_flags(_context
.flags());
189 span
.__set_startTime(std::chrono::duration_cast
<std::chrono::microseconds
>(
190 _startTimeSystem
.time_since_epoch())
193 std::chrono::duration_cast
<std::chrono::microseconds
>(_duration
)
196 std::vector
<thrift::Tag
> tags
;
197 tags
.reserve(_tags
.size());
198 std::transform(std::begin(_tags
),
200 std::back_inserter(tags
),
202 thrift::Tag thriftTag
;
203 tag
.thrift(thriftTag
);
206 span
.__set_tags(tags
);
208 std::vector
<thrift::Log
> logs
;
209 logs
.reserve(_logs
.size());
210 std::transform(std::begin(_logs
),
212 std::back_inserter(logs
),
213 [](const LogRecord
& log
) {
214 thrift::Log thriftLog
;
215 log
.thrift(thriftLog
);
218 span
.__set_logs(logs
);
221 } // namespace jaegertracing