]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/sdk/src/trace/samplers/trace_id_ratio.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / sdk / src / trace / samplers / trace_id_ratio.cc
1 // Copyright 2020, Open Telemetry Authors
2 // Copyright 2017, OpenCensus Authors
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 #include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"
17
18 #include <cmath>
19 #include <cstdint>
20 #include <stdexcept>
21
22 namespace trace_api = opentelemetry::trace;
23
24 namespace
25 {
26 /**
27 * Converts a ratio in [0, 1] to a threshold in [0, UINT64_MAX]
28 *
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
32 * uint64_t datatype
33 */
34 uint64_t CalculateThreshold(double ratio) noexcept
35 {
36 if (ratio <= 0.0)
37 return 0;
38 if (ratio >= 1.0)
39 return UINT64_MAX;
40
41 // We can't directly return ratio * UINT64_MAX.
42 //
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);
49 }
50
51 /**
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
55 * uint64_t datatype
56 */
57 uint64_t CalculateThresholdFromBuffer(const trace_api::TraceId &trace_id) noexcept
58 {
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.");
61
62 uint64_t res = 0;
63 std::memcpy(&res, &trace_id, 8);
64
65 double ratio = (double)res / UINT64_MAX;
66
67 return CalculateThreshold(ratio);
68 }
69 } // namespace
70
71 OPENTELEMETRY_BEGIN_NAMESPACE
72 namespace sdk
73 {
74 namespace trace
75 {
76 TraceIdRatioBasedSampler::TraceIdRatioBasedSampler(double ratio)
77 : threshold_(CalculateThreshold(ratio))
78 {
79 if (ratio > 1.0)
80 ratio = 1.0;
81 if (ratio < 0.0)
82 ratio = 0.0;
83 description_ = "TraceIdRatioBasedSampler{" + std::to_string(ratio) + "}";
84 }
85
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
93 {
94 if (threshold_ == 0)
95 return {Decision::DROP, nullptr};
96
97 if (CalculateThresholdFromBuffer(trace_id) <= threshold_)
98 {
99 return {Decision::RECORD_AND_SAMPLE, nullptr};
100 }
101
102 return {Decision::DROP, nullptr};
103 }
104
105 nostd::string_view TraceIdRatioBasedSampler::GetDescription() const noexcept
106 {
107 return description_;
108 }
109 } // namespace trace
110 } // namespace sdk
111 OPENTELEMETRY_END_NAMESPACE