diff --git a/exporters/logging/build.gradle.kts b/exporters/logging/build.gradle.kts
index 8107ed13a9a..ca1adf08d1a 100644
--- a/exporters/logging/build.gradle.kts
+++ b/exporters/logging/build.gradle.kts
@@ -13,6 +13,8 @@ dependencies {
api(project(":sdk:metrics"))
api(project(":sdk:logs"))
+ implementation(project(":sdk-extensions:autoconfigure-spi"))
+
testImplementation(project(":sdk:testing"))
testImplementation(project(":sdk:logs-testing"))
}
diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java
new file mode 100644
index 00000000000..e6fbd6fbc8d
--- /dev/null
+++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.exporter.logging.internal;
+
+import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider;
+import io.opentelemetry.sdk.logs.export.LogRecordExporter;
+
+/**
+ * {@link LogRecordExporter} SPI implementation for {@link SystemOutLogRecordExporter}.
+ *
+ *
This class is internal and is hence not for public use. Its APIs are unstable and can change
+ * at any time.
+ */
+public class LoggingLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider {
+ @Override
+ public LogRecordExporter createExporter(ConfigProperties config) {
+ return SystemOutLogRecordExporter.create();
+ }
+
+ @Override
+ public String getName() {
+ return "logging";
+ }
+}
diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java
new file mode 100644
index 00000000000..47605ac1154
--- /dev/null
+++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.exporter.logging.internal;
+
+import io.opentelemetry.exporter.logging.LoggingMetricExporter;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+
+/**
+ * {@link MetricExporter} SPI implementation for {@link LoggingMetricExporter}.
+ *
+ *
This class is internal and is hence not for public use. Its APIs are unstable and can change
+ * at any time.
+ */
+public class LoggingMetricExporterProvider implements ConfigurableMetricExporterProvider {
+ @Override
+ public MetricExporter createExporter(ConfigProperties config) {
+ return LoggingMetricExporter.create();
+ }
+
+ @Override
+ public String getName() {
+ return "logging";
+ }
+}
diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java
new file mode 100644
index 00000000000..5854a12fe64
--- /dev/null
+++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.exporter.logging.internal;
+
+import io.opentelemetry.exporter.logging.LoggingSpanExporter;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
+import io.opentelemetry.sdk.trace.export.SpanExporter;
+
+/**
+ * {@link SpanExporter} SPI implementation for {@link LoggingSpanExporter}.
+ *
+ *
This class is internal and is hence not for public use. Its APIs are unstable and can change
+ * at any time.
+ */
+public class LoggingSpanExporterProvider implements ConfigurableSpanExporterProvider {
+ @Override
+ public SpanExporter createExporter(ConfigProperties config) {
+ return LoggingSpanExporter.create();
+ }
+
+ @Override
+ public String getName() {
+ return "logging";
+ }
+}
diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider
new file mode 100644
index 00000000000..8d8842825ba
--- /dev/null
+++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider
@@ -0,0 +1 @@
+io.opentelemetry.exporter.logging.internal.LoggingLogRecordExporterProvider
diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider
new file mode 100644
index 00000000000..3ad21a55ccd
--- /dev/null
+++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider
@@ -0,0 +1 @@
+io.opentelemetry.exporter.logging.internal.LoggingMetricExporterProvider
diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider
new file mode 100644
index 00000000000..8806e4b9608
--- /dev/null
+++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider
@@ -0,0 +1 @@
+io.opentelemetry.exporter.logging.internal.LoggingSpanExporterProvider
diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts
index 182e6389c92..6328e6785c4 100644
--- a/sdk-extensions/autoconfigure/build.gradle.kts
+++ b/sdk-extensions/autoconfigure/build.gradle.kts
@@ -16,7 +16,6 @@ dependencies {
implementation(project(":exporters:common"))
compileOnly(project(":exporters:jaeger"))
- compileOnly(project(":exporters:logging"))
compileOnly(project(":exporters:otlp:all"))
compileOnly(project(":exporters:otlp:logs"))
compileOnly(project(":exporters:otlp:common"))
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
index 927b4eceb2f..9dd3dc19647 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
@@ -11,7 +11,6 @@
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.retry.RetryUtil;
-import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
@@ -30,6 +29,12 @@
class LogRecordExporterConfiguration {
private static final String EXPORTER_NONE = "none";
+ private static final Map EXPORTER_ARTIFACT_ID_BY_NAME;
+
+ static {
+ EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>();
+ EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging");
+ }
// Visible for test
static Map configureLogRecordExporters(
@@ -85,15 +90,18 @@ static LogRecordExporter configureExporter(
switch (name) {
case "otlp":
return configureOtlpLogs(config, meterProvider);
- case "logging":
- ClasspathUtil.checkClassExists(
- "io.opentelemetry.exporter.logging.SystemOutLogRecordExporter",
- "Logging Log Exporter",
- "opentelemetry-exporter-logging");
- return SystemOutLogRecordExporter.create();
default:
LogRecordExporter spiExporter = spiExportersManager.getByName(name);
if (spiExporter == null) {
+ String artifactId = EXPORTER_ARTIFACT_ID_BY_NAME.get(name);
+ if (artifactId != null) {
+ throw new ConfigurationException(
+ "otel.logs.exporter set to \""
+ + name
+ + "\" but "
+ + artifactId
+ + " not found on classpath. Make sure to add it as a dependency.");
+ }
throw new ConfigurationException("Unrecognized value for otel.logs.exporter: " + name);
}
return spiExporter;
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java
index ac8e6784b3f..75671f8d314 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java
@@ -10,7 +10,6 @@
import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
import io.opentelemetry.exporter.internal.retry.RetryUtil;
-import io.opentelemetry.exporter.logging.LoggingMetricExporter;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
@@ -24,12 +23,20 @@
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
import java.util.function.BiFunction;
import javax.annotation.Nullable;
final class MetricExporterConfiguration {
private static final Duration DEFAULT_EXPORT_INTERVAL = Duration.ofMinutes(1);
+ private static final Map EXPORTER_ARTIFACT_ID_BY_NAME;
+
+ static {
+ EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>();
+ EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging");
+ }
static MetricReader configureExporter(
String name,
@@ -46,12 +53,18 @@ static MetricReader configureExporter(
case "otlp":
metricExporter = configureOtlpMetrics(config);
break;
- case "logging":
- metricExporter = configureLoggingExporter();
- break;
default:
MetricExporter spiExporter = configureSpiExporter(name, config, serviceClassLoader);
if (spiExporter == null) {
+ String artifactId = EXPORTER_ARTIFACT_ID_BY_NAME.get(name);
+ if (artifactId != null) {
+ throw new ConfigurationException(
+ "otel.metrics.exporter set to \""
+ + name
+ + "\" but "
+ + artifactId
+ + " not found on classpath. Make sure to add it as a dependency.");
+ }
throw new ConfigurationException("Unrecognized value for otel.metrics.exporter: " + name);
}
metricExporter = spiExporter;
@@ -61,14 +74,6 @@ static MetricReader configureExporter(
return configurePeriodicMetricReader(config, metricExporter);
}
- private static MetricExporter configureLoggingExporter() {
- ClasspathUtil.checkClassExists(
- "io.opentelemetry.exporter.logging.LoggingMetricExporter",
- "Logging Metrics Exporter",
- "opentelemetry-exporter-logging");
- return LoggingMetricExporter.create();
- }
-
// Visible for testing.
@Nullable
static MetricExporter configureSpiExporter(
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
index a3d2c394783..89a42620b48 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
@@ -14,7 +14,6 @@
import io.opentelemetry.exporter.internal.retry.RetryUtil;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder;
-import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
@@ -27,6 +26,7 @@
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.time.Duration;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
@@ -35,6 +35,12 @@
final class SpanExporterConfiguration {
private static final String EXPORTER_NONE = "none";
+ private static final Map EXPORTER_ARTIFACT_ID_BY_NAME;
+
+ static {
+ EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>();
+ EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging");
+ }
// Visible for testing
static Map configureSpanExporters(
@@ -92,15 +98,18 @@ static SpanExporter configureExporter(
return configureJaeger(config, meterProvider);
case "zipkin":
return configureZipkin(config);
- case "logging":
- ClasspathUtil.checkClassExists(
- "io.opentelemetry.exporter.logging.LoggingSpanExporter",
- "Logging Trace Exporter",
- "opentelemetry-exporter-logging");
- return LoggingSpanExporter.create();
default:
SpanExporter spiExporter = spiExportersManager.getByName(name);
if (spiExporter == null) {
+ String artifactId = EXPORTER_ARTIFACT_ID_BY_NAME.get(name);
+ if (artifactId != null) {
+ throw new ConfigurationException(
+ "otel.traces.exporter set to \""
+ + name
+ + "\" but "
+ + artifactId
+ + " not found on classpath. Make sure to add it as a dependency.");
+ }
throw new ConfigurationException("Unrecognized value for otel.traces.exporter: " + name);
}
return spiExporter;
diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/NotOnClasspathTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/NotOnClasspathTest.java
index a4a476b2c62..f3c36438fd0 100644
--- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/NotOnClasspathTest.java
+++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/NotOnClasspathTest.java
@@ -77,8 +77,8 @@ void loggingSpans() {
"logging", EMPTY, NamedSpiManager.createEmpty(), MeterProvider.noop()))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining(
- "Logging Trace Exporter enabled but opentelemetry-exporter-logging not found on "
- + "classpath");
+ "otel.traces.exporter set to \"logging\" but opentelemetry-exporter-logging not found on classpath."
+ + " Make sure to add it as a dependency.");
}
@Test
@@ -92,8 +92,8 @@ void loggingMetrics() {
(a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining(
- "Logging Metrics Exporter enabled but opentelemetry-exporter-logging not found on "
- + "classpath");
+ "otel.metrics.exporter set to \"logging\" but opentelemetry-exporter-logging not found on classpath."
+ + " Make sure to add it as a dependency.");
}
@Test
@@ -104,8 +104,8 @@ void loggingLogs() {
"logging", EMPTY, NamedSpiManager.createEmpty(), MeterProvider.noop()))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining(
- "Logging Log Exporter enabled but opentelemetry-exporter-logging not found on "
- + "classpath");
+ "otel.logs.exporter set to \"logging\" but opentelemetry-exporter-logging not found on classpath."
+ + " Make sure to add it as a dependency.");
}
@Test