1 // Copyright 2020, Open Telemetry Authors
2 // Copyright 2017, OpenCensus Authors
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.
16 #include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"
22 namespace trace_api
= opentelemetry::trace
;
27 * Converts a ratio in [0, 1] to a threshold in [0, UINT64_MAX]
29 * @param ratio a required value top be converted to uint64_t. is
30 * bounded by 1 >= ratio >= 0.
31 * @return Returns threshold value computed after converting ratio to
34 uint64_t CalculateThreshold(double ratio
) noexcept
41 // We can't directly return ratio * UINT64_MAX.
43 // UINT64_MAX is (2^64)-1, but as a double rounds up to 2^64.
44 // For probabilities >= 1-(2^-54), the product wraps to zero!
45 // Instead, calculate the high and low 32 bits separately.
46 const double product
= UINT32_MAX
* ratio
;
47 double hi_bits
, lo_bits
= ldexp(modf(product
, &hi_bits
), 32) + product
;
48 return (static_cast<uint64_t>(hi_bits
) << 32) + static_cast<uint64_t>(lo_bits
);
52 * @param trace_id a required value to be converted to uint64_t. trace_id must
53 * at least 8 bytes long
54 * @return Returns threshold value computed after converting trace_id to
57 uint64_t CalculateThresholdFromBuffer(const trace_api::TraceId
&trace_id
) noexcept
59 // We only use the first 8 bytes of TraceId.
60 static_assert(trace_api::TraceId::kSize
>= 8, "TraceID must be at least 8 bytes long.");
63 std::memcpy(&res
, &trace_id
, 8);
65 double ratio
= (double)res
/ UINT64_MAX
;
67 return CalculateThreshold(ratio
);
71 OPENTELEMETRY_BEGIN_NAMESPACE
76 TraceIdRatioBasedSampler::TraceIdRatioBasedSampler(double ratio
)
77 : threshold_(CalculateThreshold(ratio
))
83 description_
= "TraceIdRatioBasedSampler{" + std::to_string(ratio
) + "}";
86 SamplingResult
TraceIdRatioBasedSampler::ShouldSample(
87 const trace_api::SpanContext
& /*parent_context*/,
88 trace_api::TraceId trace_id
,
89 nostd::string_view
/*name*/,
90 trace_api::SpanKind
/*span_kind*/,
91 const opentelemetry::common::KeyValueIterable
& /*attributes*/,
92 const trace_api::SpanContextKeyValueIterable
& /*links*/) noexcept
95 return {Decision::DROP
, nullptr};
97 if (CalculateThresholdFromBuffer(trace_id
) <= threshold_
)
99 return {Decision::RECORD_AND_SAMPLE
, nullptr};
102 return {Decision::DROP
, nullptr};
105 nostd::string_view
TraceIdRatioBasedSampler::GetDescription() const noexcept
111 OPENTELEMETRY_END_NAMESPACE