Skip to content

Commit 2cae0ea

Browse files
authored
feat: adding allow list instead for metric view and cardinality configuration support (#421)
* adding allow list metric view configration and adding cardinality support * removing route from allow list
1 parent 9a04d90 commit 2cae0ea

File tree

1 file changed

+99
-32
lines changed

1 file changed

+99
-32
lines changed

otel-extensions/src/main/java/org/hypertrace/agent/otel/extensions/MetricViewConfiguration.java

Lines changed: 99 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,112 @@
1717
package org.hypertrace.agent.otel.extensions;
1818

1919
import io.opentelemetry.sdk.metrics.View;
20+
import java.lang.reflect.Field;
2021
import java.util.Arrays;
2122
import java.util.HashSet;
2223
import java.util.Set;
24+
import java.util.logging.Level;
25+
import java.util.logging.Logger;
2326

2427
public class MetricViewConfiguration {
28+
private static final Logger logger = Logger.getLogger(MetricViewConfiguration.class.getName());
2529

30+
// OpenTelemetry's cardinality limit property
31+
private static final String OTEL_CARDINALITY_LIMIT =
32+
"otel.experimental.metrics.cardinality.limit";
33+
34+
// Default HTTP attributes to include
35+
private static final Set<String> KEYS_TO_RETAIN =
36+
new HashSet<>(
37+
Arrays.asList(
38+
"http.method",
39+
"http.status_code",
40+
"http.scheme",
41+
"rpc.method",
42+
"rpc.grpc.status_code",
43+
"rpc.service"));
44+
45+
/**
46+
* Creates a View with HTTP attribute filtering and cardinality limit based on OpenTelemetry
47+
* configuration.
48+
*
49+
* <p>The cardinality limit is set from the OpenTelemetry system property or environment variable:
50+
*
51+
* <ul>
52+
* <li>System property: otel.experimental.metrics.cardinality.limit
53+
* <li>Environment variable: OTEL_EXPERIMENTAL_METRICS_CARDINALITY_LIMIT
54+
* </ul>
55+
*
56+
* @return a configured View with HTTP attribute filtering and cardinality limit
57+
*/
2658
public static View createView() {
27-
// Attributes to exclude
28-
Set<String> excludedAttributes =
29-
new HashSet<>(
30-
Arrays.asList(
31-
"net.sock.peer.addr",
32-
"net.sock.host.addr",
33-
"net.sock.peer.port",
34-
"net.sock.host.port",
35-
"net.host.name",
36-
"net.host.port",
37-
"net.protocol.name",
38-
"net.protocol.version",
39-
"http.user_agent",
40-
"enduser.id",
41-
"http.client_ip",
42-
"http.route",
43-
"http.target",
44-
"http.request_content_length",
45-
"http.response_content_length",
46-
"user_agent.original"));
47-
48-
// Build the view
49-
return View.builder()
50-
.setAttributeFilter(
51-
attributes -> {
52-
for (String attribute : excludedAttributes) {
53-
if (attributes.contains(attribute)) {
59+
// Build the view with our attribute filter
60+
View view =
61+
View.builder()
62+
.setAttributeFilter(
63+
attributes -> {
64+
for (String attribute : KEYS_TO_RETAIN) {
65+
if (attributes.contains(attribute)) {
66+
return true;
67+
}
68+
}
5469
return false;
55-
}
56-
}
57-
return true;
58-
})
59-
.build();
70+
})
71+
.build();
72+
73+
Integer cardinalityLimit = getCardinalityLimit();
74+
75+
/* Only apply cardinality limit if it's explicitly configured
76+
The global cardinality configuration field 'otel.experimental.metrics.cardinality.limit' does not apply for custom views
77+
Also the view builder, does not have a setter for cardinality limit in 1.33.0 SDK we use.
78+
So using reflection to set the cardinality limit
79+
*/
80+
if (cardinalityLimit != null) {
81+
try {
82+
// Get the View class
83+
Class<?> viewClass = view.getClass();
84+
85+
// Get the cardinalityLimit field
86+
Field cardinalityLimitField = viewClass.getDeclaredField("cardinalityLimit");
87+
cardinalityLimitField.setAccessible(true);
88+
89+
// Set the cardinality limit
90+
cardinalityLimitField.set(view, cardinalityLimit);
91+
92+
} catch (Exception e) {
93+
logger.log(Level.WARNING, "Failed to set cardinality limit using reflection", e);
94+
}
95+
}
96+
97+
return view;
98+
}
99+
100+
/**
101+
* Gets the cardinality limit from OpenTelemetry's system property or environment variable.
102+
*
103+
* @return the configured cardinality limit, or null if not configured
104+
*/
105+
private static Integer getCardinalityLimit() {
106+
String limitValue = getProperty(OTEL_CARDINALITY_LIMIT);
107+
108+
if (limitValue != null && !limitValue.isEmpty()) {
109+
try {
110+
return Integer.parseInt(limitValue);
111+
} catch (NumberFormatException e) {
112+
logger.log(Level.WARNING, "Invalid cardinality limit value: " + limitValue, e);
113+
}
114+
}
115+
116+
return null; // No explicit configuration
117+
}
118+
119+
/**
120+
* Gets a property from system properties or environment variables.
121+
*
122+
* @param name the property name
123+
* @return the property value, or null if not set
124+
*/
125+
private static String getProperty(String name) {
126+
return System.getProperty(name, System.getenv(name.replaceAll("\\.", "_").toUpperCase()));
60127
}
61128
}

0 commit comments

Comments
 (0)