Skip to content

Commit 5b5503f

Browse files
jackshiraziCopilot
andauthored
[dynamic control] Add trace sampling validation (#2604)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent a0135db commit 5b5503f

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.dynamic.policy;
7+
8+
import javax.annotation.Nullable;
9+
10+
public interface PolicyValidator {
11+
/**
12+
* Validates a policy configuration provided as a JSON string.
13+
*
14+
* @param json The JSON string containing the policy configuration.
15+
* @return The validated {@link TelemetryPolicy}, or {@code null} if the JSON does not contain a
16+
* valid policy for this validator.
17+
*/
18+
@Nullable
19+
TelemetryPolicy validate(String json);
20+
21+
/**
22+
* Returns the type of the policy this validator handles.
23+
*
24+
* @return The policy type string (e.g., "trace-sampling").
25+
*/
26+
String getPolicyType();
27+
28+
/**
29+
* Validates a policy configuration provided as a key-value pair (alias).
30+
*
31+
* <p>This is intended for simple configuration cases where a full JSON object is not necessary.
32+
*
33+
* @param key The alias key (e.g., "trace-sampling.probability").
34+
* @param value The value associated with the key.
35+
* @return The validated {@link TelemetryPolicy}, or {@code null} if the key/value pair is invalid
36+
* or not handled by this validator.
37+
*/
38+
@Nullable
39+
default TelemetryPolicy validateAlias(String key, String value) {
40+
throw new UnsupportedOperationException(
41+
"Alias validation is not supported by validator "
42+
+ getClass().getName()
43+
+ " for key "
44+
+ key);
45+
}
46+
47+
/**
48+
* Returns the alias key supported by this validator, if any.
49+
*
50+
* @return The alias key string, or {@code null} if aliases are not supported.
51+
*/
52+
@Nullable
53+
default String getAlias() {
54+
return null;
55+
}
56+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.dynamic.policy;
7+
8+
import com.fasterxml.jackson.core.JsonProcessingException;
9+
import com.fasterxml.jackson.databind.JsonNode;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import java.util.logging.Logger;
12+
import javax.annotation.Nullable;
13+
14+
/**
15+
* Validator for trace sampling policies.
16+
*
17+
* <p>This validator handles the "trace-sampling" policy type and supports the
18+
* "trace-sampling.probability" alias.
19+
*/
20+
public final class TraceSamplingValidator implements PolicyValidator {
21+
private static final Logger logger = Logger.getLogger(TraceSamplingValidator.class.getName());
22+
private static final ObjectMapper MAPPER = new ObjectMapper();
23+
24+
@Override
25+
public String getPolicyType() {
26+
return "trace-sampling";
27+
}
28+
29+
@Override
30+
public String getAlias() {
31+
return "trace-sampling.probability";
32+
}
33+
34+
@Override
35+
@Nullable
36+
public TelemetryPolicy validate(String json) {
37+
try {
38+
JsonNode node = MAPPER.readTree(json);
39+
if (node.has(getPolicyType())) {
40+
JsonNode spec = node.get(getPolicyType());
41+
if (spec.has("probability")) {
42+
JsonNode probNode = spec.get("probability");
43+
if (probNode.isNumber()) {
44+
double d = probNode.asDouble();
45+
if (d >= 0.0 && d <= 1.0) {
46+
return new TelemetryPolicy(getPolicyType(), spec);
47+
}
48+
}
49+
}
50+
}
51+
} catch (JsonProcessingException e) {
52+
// Not valid JSON for this validator
53+
}
54+
logger.info("Invalid trace-sampling JSON: " + json);
55+
return null;
56+
}
57+
58+
@Override
59+
@Nullable
60+
public TelemetryPolicy validateAlias(String key, String value) {
61+
if (getAlias() != null && getAlias().equals(key)) {
62+
try {
63+
double d = Double.parseDouble(value);
64+
if (d >= 0.0 && d <= 1.0) {
65+
JsonNode spec = MAPPER.createObjectNode().put("probability", d);
66+
return new TelemetryPolicy(getPolicyType(), spec);
67+
}
68+
} catch (NumberFormatException e) {
69+
// invalid
70+
}
71+
logger.info("Ignoring invalid trace-sampling.probability value: " + value);
72+
}
73+
return null;
74+
}
75+
}

0 commit comments

Comments
 (0)