Skip to content

Commit 88641a1

Browse files
authored
dynatrace sampler: avoid div by zero (#40220)
<!-- !!!ATTENTION!!! If you are fixing *any* crash or *any* potential security issue, *do not* open a pull request in this repo. Please report the issue via emailing [email protected] where the issue will be triaged appropriately. Thank you in advance for helping to keep Envoy secure. !!!ATTENTION!!! For an explanation of how to fill out the fields, please see the relevant section in [PULL_REQUESTS.md](https://github.com/envoyproxy/envoy/blob/main/PULL_REQUESTS.md) --> Commit Message: Prevent division by zero in dynatrace sampling controller in case `total_wanted < top_k_size`. Additional Description: Risk Level: low Testing: unitest Docs Changes: - Release Notes: - Platform Specific Features: - Fixes fixes: #37983 Signed-off-by: Gerhard Stöbich <[email protected]>
1 parent 3776520 commit 88641a1

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

source/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,9 @@ void SamplingController::calculateSamplingExponents(
123123
return;
124124
}
125125

126-
// number of requests which are allowed for every entry
127-
const uint32_t allowed_per_entry = total_wanted / top_k_size;
128-
129126
for (auto& counter : top_k) {
130127
// allowed multiplicity for this entry
131-
auto wanted_multiplicity = counter.getValue() / allowed_per_entry;
128+
auto wanted_multiplicity = counter.getValue() * top_k_size / total_wanted;
132129
auto sampling_state = new_sampling_exponents.find(counter.getItem());
133130
// sampling exponent has to be a power of 2. Find the exponent to have multiplicity near to
134131
// wanted_multiplicity

test/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller_test.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,24 @@ TEST(SamplingControllerTest, TestWithOneAllowedSpan) {
8989
EXPECT_EQ(sc.getSamplingState("1").getMultiplicity(), 1);
9090
}
9191

92+
// Test with 1 root span per minute and more offered entries
93+
TEST(SamplingControllerTest, TestWithOneAllowedSpanMoreEntries) {
94+
auto scf = std::make_unique<TestSamplerConfigProvider>(1);
95+
SamplingController sc(std::move(scf));
96+
sc.update();
97+
EXPECT_EQ(sc.getSamplingState("1").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT);
98+
offerEntry(sc, "1", 1);
99+
offerEntry(sc, "2", 1);
100+
offerEntry(sc, "3", 1);
101+
EXPECT_EQ(sc.getSamplingState("1").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT);
102+
EXPECT_EQ(sc.getSamplingState("2").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT);
103+
EXPECT_EQ(sc.getSamplingState("3").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT);
104+
sc.update();
105+
EXPECT_EQ(sc.getSamplingState("1").getMultiplicity(), 2);
106+
EXPECT_EQ(sc.getSamplingState("2").getMultiplicity(), 2);
107+
EXPECT_EQ(sc.getSamplingState("3").getMultiplicity(), 1);
108+
}
109+
92110
// Test with StreamSummary size not exceeded
93111
TEST(SamplingControllerTest, TestStreamSummarySizeNotExceeded) {
94112
auto scf = std::make_unique<TestSamplerConfigProvider>();

0 commit comments

Comments
 (0)