Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
adding allow list metric view configration and adding cardinality sup…
…port
  • Loading branch information
thugrock7 committed Jun 3, 2025
commit f843bef21dda6442cf20b7af9ad58add6043b126
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,113 @@
package org.hypertrace.agent.otel.extensions;

import io.opentelemetry.sdk.metrics.View;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

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

// OpenTelemetry's cardinality limit property
private static final String OTEL_CARDINALITY_LIMIT =
"otel.experimental.metrics.cardinality.limit";

// Default HTTP attributes to include
private static final Set<String> KEYS_TO_RETAIN =
new HashSet<>(
Arrays.asList(
"http.method",
"http.status_code",
"http.scheme",
"http.route",
Comment thread
thugrock7 marked this conversation as resolved.
Outdated
"rpc.method",
"rpc.grpc.status_code",
"rpc.service"));

/**
* Creates a View with HTTP attribute filtering and cardinality limit based on OpenTelemetry
* configuration.
*
* <p>The cardinality limit is set from the OpenTelemetry system property or environment variable:
*
* <ul>
* <li>System property: otel.experimental.metrics.cardinality.limit
* <li>Environment variable: OTEL_EXPERIMENTAL_METRICS_CARDINALITY_LIMIT
* </ul>
*
* @return a configured View with HTTP attribute filtering and cardinality limit
*/
public static View createView() {
// Attributes to exclude
Set<String> excludedAttributes =
new HashSet<>(
Arrays.asList(
"net.sock.peer.addr",
"net.sock.host.addr",
"net.sock.peer.port",
"net.sock.host.port",
"net.host.name",
"net.host.port",
"net.protocol.name",
"net.protocol.version",
"http.user_agent",
"enduser.id",
"http.client_ip",
"http.route",
"http.target",
"http.request_content_length",
"http.response_content_length",
"user_agent.original"));

// Build the view
return View.builder()
.setAttributeFilter(
attributes -> {
for (String attribute : excludedAttributes) {
if (attributes.contains(attribute)) {
// Build the view with our attribute filter
View view =
View.builder()
.setAttributeFilter(
attributes -> {
for (String attribute : KEYS_TO_RETAIN) {
if (attributes.contains(attribute)) {
return true;
}
}
return false;
}
}
return true;
})
.build();
})
.build();

Integer cardinalityLimit = getCardinalityLimit();

/* Only apply cardinality limit if it's explicitly configured
The global cardinality configuration field 'otel.experimental.metrics.cardinality.limit' does not apply for custom views
Also the view builder, does not have a setter for cardinality limit in 1.33.0 SDK we use.
So using reflection to set the cardinality limit
*/
if (cardinalityLimit != null) {
try {
// Get the View class
Class<?> viewClass = view.getClass();

// Get the cardinalityLimit field
Field cardinalityLimitField = viewClass.getDeclaredField("cardinalityLimit");
cardinalityLimitField.setAccessible(true);

// Set the cardinality limit
cardinalityLimitField.set(view, cardinalityLimit);

} catch (Exception e) {
logger.log(Level.WARNING, "Failed to set cardinality limit using reflection", e);
}
}

return view;
}

/**
* Gets the cardinality limit from OpenTelemetry's system property or environment variable.
*
* @return the configured cardinality limit, or null if not configured
*/
private static Integer getCardinalityLimit() {
String limitValue = getProperty(OTEL_CARDINALITY_LIMIT);

if (limitValue != null && !limitValue.isEmpty()) {
try {
return Integer.parseInt(limitValue);
} catch (NumberFormatException e) {
logger.log(Level.WARNING, "Invalid cardinality limit value: " + limitValue, e);
}
}

return null; // No explicit configuration
}

/**
* Gets a property from system properties or environment variables.
*
* @param name the property name
* @return the property value, or null if not set
*/
private static String getProperty(String name) {
return System.getProperty(name, System.getenv(name.replaceAll("\\.", "_").toUpperCase()));
}
}
Loading