diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 1b62011e42c..dcf7aa0bb43 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -18,16 +18,21 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Predicate; +import java.util.logging.Logger; import javax.annotation.Nullable; /** A builder for {@link PrometheusHttpServer}. */ public final class PrometheusHttpServerBuilder { static final int DEFAULT_PORT = 9464; - private static final String DEFAULT_HOST = "0.0.0.0"; + private static final String DEFAULT_HOST = "localhost"; private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; + private static final Logger LOGGER = + Logger.getLogger(PrometheusHttpServerBuilder.class.getName()); - private String host = DEFAULT_HOST; + // Temporarily nullable to detect when it's not set and log warning about 0.0.0.0 -> localhost + // change + @Nullable private String host; private int port = DEFAULT_PORT; private PrometheusRegistry prometheusRegistry = new PrometheusRegistry(); private PrometheusMetricReaderBuilder metricReaderBuilder = PrometheusMetricReader.builder(); @@ -51,7 +56,12 @@ public final class PrometheusHttpServerBuilder { this.authenticator = builder.authenticator; } - /** Sets the host to bind to. If unset, defaults to {@value #DEFAULT_HOST}. */ + /** + * Sets the host to bind to. If unset, defaults to {@value #DEFAULT_HOST}. + * + *

Previously defaulted to {@code 0.0.0.0}. To restore the old behavior, set host to {@code + * 0.0.0.0} explicitly. + */ public PrometheusHttpServerBuilder setHost(String host) { requireNonNull(host, "host"); checkArgument(!host.isEmpty(), "host must not be empty"); @@ -173,9 +183,17 @@ public PrometheusHttpServer build() { "MemoryMode REUSEABLE_DATA cannot be used with custom executor, " + "since data may be corrupted if reading metrics concurrently"); } + String resolvedHost = host; + if (resolvedHost == null) { + // TODO (jack-berg): Remove log after 1.64.0 release + LOGGER.info( + "PrometheusHttpServer host not set, defaulting to localhost. Previously defaulted to 0.0.0.0. " + + "If you depend on the old behavior, set host to 0.0.0.0 explicitly."); + resolvedHost = DEFAULT_HOST; + } return new PrometheusHttpServer( new PrometheusHttpServerBuilder(this), // copy to prevent modification - host, + resolvedHost, port, executor, prometheusRegistry, diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index 4c29d84e85b..2f07730a198 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -59,7 +59,8 @@ void createMetricReader_Default() throws IOException { .extracting("server", as(InstanceOfAssertFactories.type(HttpServer.class))) .satisfies( server -> { - assertThat(server.getAddress().getAddress().isAnyLocalAddress()).isTrue(); + assertThat(server.getAddress().getHostName()) + .isIn("localhost", "127.0.0.1", "kubernetes.docker.internal"); assertThat(server.getAddress().getPort()).isEqualTo(9464); }); assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA);