diff --git a/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/FlagEvalMetrics.java b/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/FlagEvalMetrics.java index 83ca85af9b0..50f67fccc4f 100644 --- a/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/FlagEvalMetrics.java +++ b/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/FlagEvalMetrics.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.time.Duration; import org.slf4j.Logger; @@ -31,6 +32,10 @@ class FlagEvalMetrics implements Closeable { private static final String ENDPOINT_ENV = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"; // Generic env var fallback (base URL, /v1/metrics is appended) private static final String ENDPOINT_GENERIC_ENV = "OTEL_EXPORTER_OTLP_ENDPOINT"; + // OTel standard env vars for service name + private static final String SERVICE_NAME_ENV = "OTEL_SERVICE_NAME"; + private static final AttributeKey SERVICE_NAME_KEY = + AttributeKey.stringKey("service.name"); private static final AttributeKey ATTR_FLAG_KEY = AttributeKey.stringKey("feature_flag.key"); @@ -68,8 +73,12 @@ class FlagEvalMetrics implements Closeable { PeriodicMetricReader reader = PeriodicMetricReader.builder(exporter).setInterval(EXPORT_INTERVAL).build(); + // Build resource with service name from OTEL_SERVICE_NAME env var + // Resource.getDefault() only provides unknown_service:java, so we read env vars manually + Resource resource = buildResource(); + SdkMeterProvider sdkMeterProvider = - SdkMeterProvider.builder().registerMetricReader(reader).build(); + SdkMeterProvider.builder().setResource(resource).registerMetricReader(reader).build(); meterProvider = sdkMeterProvider; Meter meter = sdkMeterProvider.meterBuilder(METER_NAME).build(); @@ -83,9 +92,9 @@ class FlagEvalMetrics implements Closeable { log.debug("Flag evaluation metrics initialized, exporting to {}", endpoint); } catch (NoClassDefFoundError e) { log.error( - "OpenTelemetry SDK is not on the classpath — evaluation metrics disabled. " - + "Add opentelemetry-sdk-metrics and opentelemetry-exporter-otlp to your dependencies " - + "to enable flag evaluation metrics.", + "OpenTelemetry SDK is not on the classpath — evaluation metrics disabled. Add" + + " opentelemetry-sdk-metrics and opentelemetry-exporter-otlp to your dependencies to" + + " enable flag evaluation metrics.", e); counter = null; meterProvider = null; @@ -154,4 +163,17 @@ void shutdown() { } } } + + /** + * Builds a Resource with the service name from OTEL_SERVICE_NAME environment variable. Falls back + * to Resource.getDefault() if OTEL_SERVICE_NAME is not set. + */ + private static Resource buildResource() { + String serviceName = ConfigHelper.env(SERVICE_NAME_ENV); + if (serviceName != null && !serviceName.isEmpty()) { + return Resource.getDefault() + .merge(Resource.builder().put(SERVICE_NAME_KEY, serviceName).build()); + } + return Resource.getDefault(); + } }