diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java index 0098f7188f0..80262f1f0fe 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentation.java @@ -13,7 +13,9 @@ import io.opentelemetry.sdk.common.internal.SemConvConstants; import io.opentelemetry.sdk.common.internal.Signal; import io.opentelemetry.sdk.common.internal.StandardComponentId; +import java.net.MalformedURLException; import java.net.URI; +import java.net.URL; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -55,10 +57,22 @@ public ExporterInstrumentation( static Attributes extractServerAttributes(URI httpEndpoint) { AttributesBuilder builder = Attributes.builder(); String host = httpEndpoint.getHost(); + int port = httpEndpoint.getPort(); + if (host == null) { + // URI.getHost() returns null for some valid DNS names (JDK-8188305); URL accepts them. + try { + URL url = httpEndpoint.toURL(); + if (!url.getHost().isEmpty()) { + host = url.getHost(); + } + port = url.getPort(); + } catch (MalformedURLException e) { + // Not a URL either, leave host unset. + } + } if (host != null) { builder.put(SemConvConstants.SERVER_ADDRESS, host); } - int port = httpEndpoint.getPort(); if (port == -1) { String scheme = httpEndpoint.getScheme(); if ("https".equals(scheme)) { diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java index 678e6b0b81e..c9d0a8024e7 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/metrics/ExporterInstrumentationTest.java @@ -153,4 +153,24 @@ void serverAttributesUnknownScheme() { .containsEntry(SemConvConstants.SERVER_ADDRESS, "foo") .containsEntry(SemConvConstants.SERVER_PORT, 1234); } + + @Test + void serverAttributesHostNotParsedByUri() { + // A label starting with a digit is a valid DNS name, but URI.getHost() returns null for it. + assertThat(URI.create("http://otlp.1234-ns:4318/v1/traces").getHost()).isNull(); + + assertThat( + ExporterInstrumentation.extractServerAttributes( + URI.create("http://otlp.1234-ns:4318/v1/traces"))) + .hasSize(2) + .containsEntry(SemConvConstants.SERVER_ADDRESS, "otlp.1234-ns") + .containsEntry(SemConvConstants.SERVER_PORT, 4318); + + assertThat( + ExporterInstrumentation.extractServerAttributes( + URI.create("https://otlp.1234-ns/v1/traces"))) + .hasSize(2) + .containsEntry(SemConvConstants.SERVER_ADDRESS, "otlp.1234-ns") + .containsEntry(SemConvConstants.SERVER_PORT, 443); + } }