diff --git a/pom.xml b/pom.xml
index dc35b5955fe13..6f5c169e9cf23 100644
--- a/pom.xml
+++ b/pom.xml
@@ -189,6 +189,7 @@
presto-hudi
presto-native-execution
presto-router
+ presto-open-telemetry
@@ -850,6 +851,12 @@
${project.version}
+
+ com.facebook.presto
+ presto-open-telemetry
+ ${project.version}
+
+
com.facebook.hive
hive-dwrf
@@ -2094,6 +2101,60 @@
stream
2.9.5
+
+
+ io.opentelemetry
+ opentelemetry-api
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-context
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-exporter-otlp
+ 1.19.0
+
+
+ com.squareup.okhttp3
+ okhttp
+
+
+
+
+
+ io.opentelemetry
+ opentelemetry-extension-trace-propagators
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-sdk
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-sdk-common
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-sdk-trace
+ 1.19.0
+
+
+
+ io.opentelemetry
+ opentelemetry-semconv
+ 1.19.0-alpha
+
diff --git a/presto-main/src/main/java/com/facebook/presto/server/HttpRequestSessionContext.java b/presto-main/src/main/java/com/facebook/presto/server/HttpRequestSessionContext.java
index a7b6be3f7a34b..1dce82d662f7c 100644
--- a/presto-main/src/main/java/com/facebook/presto/server/HttpRequestSessionContext.java
+++ b/presto-main/src/main/java/com/facebook/presto/server/HttpRequestSessionContext.java
@@ -22,6 +22,7 @@
import com.facebook.presto.spi.security.SelectedRole;
import com.facebook.presto.spi.session.ResourceEstimates;
import com.facebook.presto.spi.tracing.Tracer;
+import com.facebook.presto.spi.tracing.TracerHandle;
import com.facebook.presto.spi.tracing.TracerProvider;
import com.facebook.presto.sql.parser.ParsingException;
import com.facebook.presto.sql.parser.ParsingOptions;
@@ -211,19 +212,39 @@ else if (nameParts.size() == 2) {
this.sessionFunctions = parseSessionFunctionHeader(servletRequest);
this.sessionPropertyManager = requireNonNull(sessionPropertyManager, "sessionPropertyManager is null");
- String tunnelTraceId = trimEmptyToNull(servletRequest.getHeader(PRESTO_TRACE_TOKEN));
+
+ Map requestHeaders = getRequestHeaders(servletRequest);
+ TracerHandle tracerHandle = tracerProvider.getHandleGenerator().apply(requestHeaders);
+
if (isTracingEnabled()) {
- this.tracer = Optional.of(requireNonNull(tracerProvider.getNewTracer(), "tracer is null"));
+ this.tracer = Optional.of(requireNonNull(tracerProvider.getNewTracer(tracerHandle), "tracer is null"));
+ traceToken = Optional.ofNullable(this.tracer.get().getTracerId());
+ }
+ else {
+ this.tracer = Optional.of(NoopTracerProvider.NOOP_TRACER);
// If tunnel trace token is null, we expose the Presto tracing id.
// Otherwise we preserve the ability of trace token tunneling but
// still trace Presto internally for aggregation purposes.
- traceToken = Optional.ofNullable(tunnelTraceId == null ? this.tracer.get().getTracerId() : tunnelTraceId);
+ String tunnelTraceId = trimEmptyToNull(servletRequest.getHeader(PRESTO_TRACE_TOKEN));
+ if (tunnelTraceId != null) {
+ traceToken = Optional.of(tunnelTraceId);
+ }
+ else {
+ traceToken = Optional.ofNullable(tracerHandle.getTraceToken());
+ }
}
- else {
- this.tracer = Optional.of(NoopTracerProvider.NOOP_TRACER);
- traceToken = Optional.ofNullable(tunnelTraceId);
+ }
+
+ private static Map getRequestHeaders(HttpServletRequest servletRequest)
+ {
+ ImmutableMap.Builder headers = ImmutableMap.builder();
+ Enumeration headerNames = servletRequest.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String header = headerNames.nextElement();
+ headers.put(header, servletRequest.getHeader(header));
}
+ return headers.build();
}
public static List splitSessionHeader(Enumeration headers)
@@ -502,7 +523,7 @@ public Optional getTracer()
*/
private boolean isTracingEnabled()
{
- String clientValue = systemProperties.getOrDefault(DISTRIBUTED_TRACING_MODE, TracingConfig.DistributedTracingMode.NO_TRACE.name());
+ String clientValue = systemProperties.getOrDefault(DISTRIBUTED_TRACING_MODE, "");
// Client session setting overrides everything.
if (clientValue.equalsIgnoreCase(TracingConfig.DistributedTracingMode.ALWAYS_TRACE.name())) {
@@ -511,13 +532,13 @@ private boolean isTracingEnabled()
if (clientValue.equalsIgnoreCase(TracingConfig.DistributedTracingMode.NO_TRACE.name())) {
return false;
}
+ if (clientValue.equalsIgnoreCase(TracingConfig.DistributedTracingMode.SAMPLE_BASED.name())) {
+ return true;
+ }
- // Client not set, we then take system default value, and only init
- // tracing if it's SAMPLE_BASED (TracingConfig prohibits you to
- // configure system default to be ALWAYS_TRACE). If property manager
- // not provided then false.
+ // Client not set, we then take system default value if ALWAYS_TRACE (SAMPLE_BASED disabled). If property manager not provided then false.
return sessionPropertyManager
- .map(manager -> manager.decodeSystemPropertyValue(DISTRIBUTED_TRACING_MODE, null, TracingConfig.DistributedTracingMode.class) == TracingConfig.DistributedTracingMode.SAMPLE_BASED)
+ .map(manager -> manager.decodeSystemPropertyValue(DISTRIBUTED_TRACING_MODE, null, String.class).equalsIgnoreCase(TracingConfig.DistributedTracingMode.ALWAYS_TRACE.name()))
.orElse(false);
}
diff --git a/presto-main/src/main/java/com/facebook/presto/server/PluginManager.java b/presto-main/src/main/java/com/facebook/presto/server/PluginManager.java
index b6c205a47deba..5caf081fce71d 100644
--- a/presto-main/src/main/java/com/facebook/presto/server/PluginManager.java
+++ b/presto-main/src/main/java/com/facebook/presto/server/PluginManager.java
@@ -39,9 +39,11 @@
import com.facebook.presto.spi.session.SessionPropertyConfigurationManagerFactory;
import com.facebook.presto.spi.statistics.HistoryBasedPlanStatisticsProvider;
import com.facebook.presto.spi.storage.TempStorageFactory;
+import com.facebook.presto.spi.tracing.TracerProvider;
import com.facebook.presto.spi.ttl.ClusterTtlProviderFactory;
import com.facebook.presto.spi.ttl.NodeTtlFetcherFactory;
import com.facebook.presto.storage.TempStorageManager;
+import com.facebook.presto.tracing.TracerProviderManager;
import com.facebook.presto.ttl.clusterttlprovidermanagers.ClusterTtlProviderManager;
import com.facebook.presto.ttl.nodettlfetchermanagers.NodeTtlFetcherManager;
import com.google.common.collect.ImmutableList;
@@ -117,6 +119,7 @@ public class PluginManager
private final AtomicBoolean pluginsLoaded = new AtomicBoolean();
private final ImmutableSet disabledConnectors;
private final HistoryBasedPlanStatisticsManager historyBasedPlanStatisticsManager;
+ private final TracerProviderManager tracerProviderManager;
@Inject
public PluginManager(
@@ -134,7 +137,8 @@ public PluginManager(
SessionPropertyDefaults sessionPropertyDefaults,
NodeTtlFetcherManager nodeTtlFetcherManager,
ClusterTtlProviderManager clusterTtlProviderManager,
- HistoryBasedPlanStatisticsManager historyBasedPlanStatisticsManager)
+ HistoryBasedPlanStatisticsManager historyBasedPlanStatisticsManager,
+ TracerProviderManager tracerProviderManager)
{
requireNonNull(nodeInfo, "nodeInfo is null");
requireNonNull(config, "config is null");
@@ -162,6 +166,7 @@ public PluginManager(
this.clusterTtlProviderManager = requireNonNull(clusterTtlProviderManager, "clusterTtlProviderManager is null");
this.disabledConnectors = requireNonNull(config.getDisabledConnectors(), "disabledConnectors is null");
this.historyBasedPlanStatisticsManager = requireNonNull(historyBasedPlanStatisticsManager, "historyBasedPlanStatisticsManager is null");
+ this.tracerProviderManager = requireNonNull(tracerProviderManager, "tracerProviderManager is null");
}
public void loadPlugins()
@@ -297,6 +302,11 @@ public void installPlugin(Plugin plugin)
log.info("Registering plan statistics provider %s", historyBasedPlanStatisticsProvider.getName());
historyBasedPlanStatisticsManager.addHistoryBasedPlanStatisticsProviderFactory(historyBasedPlanStatisticsProvider);
}
+
+ for (TracerProvider tracerProvider : plugin.getTracerProviders()) {
+ log.info("Registering tracer provider %s", tracerProvider.getName());
+ tracerProviderManager.addTracerProviderFactory(tracerProvider);
+ }
}
private URLClassLoader buildClassLoader(String plugin)
diff --git a/presto-main/src/main/java/com/facebook/presto/server/PrestoServer.java b/presto-main/src/main/java/com/facebook/presto/server/PrestoServer.java
index 3c2143e5ea3fb..fa119ff0c6840 100644
--- a/presto-main/src/main/java/com/facebook/presto/server/PrestoServer.java
+++ b/presto-main/src/main/java/com/facebook/presto/server/PrestoServer.java
@@ -50,6 +50,7 @@
import com.facebook.presto.sql.parser.SqlParserOptions;
import com.facebook.presto.storage.TempStorageManager;
import com.facebook.presto.storage.TempStorageModule;
+import com.facebook.presto.tracing.TracerProviderManager;
import com.facebook.presto.ttl.clusterttlprovidermanagers.ClusterTtlProviderManager;
import com.facebook.presto.ttl.clusterttlprovidermanagers.ClusterTtlProviderManagerModule;
import com.facebook.presto.ttl.nodettlfetchermanagers.NodeTtlFetcherManager;
@@ -174,6 +175,7 @@ public void run()
injector.getInstance(QueryPrerequisitesManager.class).loadQueryPrerequisites();
injector.getInstance(NodeTtlFetcherManager.class).loadNodeTtlFetcher();
injector.getInstance(ClusterTtlProviderManager.class).loadClusterTtlProvider();
+ injector.getInstance(TracerProviderManager.class).loadTracerProvider();
startAssociatedProcesses(injector);
diff --git a/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java b/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java
index 48a7c1fd8c7ba..86d8fdf5a450b 100644
--- a/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java
+++ b/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java
@@ -149,7 +149,6 @@
import com.facebook.presto.spi.relation.DomainTranslator;
import com.facebook.presto.spi.relation.PredicateCompiler;
import com.facebook.presto.spi.relation.VariableReferenceExpression;
-import com.facebook.presto.spi.tracing.TracerProvider;
import com.facebook.presto.spiller.FileSingleStreamSpillerFactory;
import com.facebook.presto.spiller.GenericPartitioningSpillerFactory;
import com.facebook.presto.spiller.GenericSpillerFactory;
@@ -195,8 +194,7 @@
import com.facebook.presto.sql.tree.Expression;
import com.facebook.presto.sql.tree.FunctionCall;
import com.facebook.presto.statusservice.NodeStatusService;
-import com.facebook.presto.tracing.NoopTracerProvider;
-import com.facebook.presto.tracing.SimpleTracerProvider;
+import com.facebook.presto.tracing.TracerProviderManager;
import com.facebook.presto.tracing.TracingConfig;
import com.facebook.presto.transaction.TransactionManagerConfig;
import com.facebook.presto.type.TypeDeserializer;
@@ -245,8 +243,6 @@
import static com.facebook.drift.server.guice.DriftServerBinder.driftServerBinder;
import static com.facebook.presto.execution.scheduler.NodeSchedulerConfig.NetworkTopologyType.FLAT;
import static com.facebook.presto.execution.scheduler.NodeSchedulerConfig.NetworkTopologyType.LEGACY;
-import static com.facebook.presto.tracing.TracingConfig.TracerType.NOOP;
-import static com.facebook.presto.tracing.TracingConfig.TracerType.SIMPLE;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
@@ -741,15 +737,7 @@ public ListeningExecutorService createResourceManagerExecutor(ResourceManagerCon
// Distributed tracing
configBinder(binder).bindConfig(TracingConfig.class);
- install(installModuleIf(
- TracingConfig.class,
- config -> !config.getEnableDistributedTracing() || NOOP.equalsIgnoreCase(config.getTracerType()),
- moduleBinder -> moduleBinder.bind(TracerProvider.class).to(NoopTracerProvider.class).in(Scopes.SINGLETON)));
-
- install(installModuleIf(
- TracingConfig.class,
- config -> config.getEnableDistributedTracing() && SIMPLE.equalsIgnoreCase(config.getTracerType()),
- moduleBinder -> moduleBinder.bind(TracerProvider.class).to(SimpleTracerProvider.class).in(Scopes.SINGLETON)));
+ binder.bind(TracerProviderManager.class).in(Scopes.SINGLETON);
//Optional Status Detector
newOptionalBinder(binder, NodeStatusService.class);
diff --git a/presto-main/src/main/java/com/facebook/presto/server/protocol/QueuedStatementResource.java b/presto-main/src/main/java/com/facebook/presto/server/protocol/QueuedStatementResource.java
index f0d76308d891e..67f4eefcef8dc 100644
--- a/presto-main/src/main/java/com/facebook/presto/server/protocol/QueuedStatementResource.java
+++ b/presto-main/src/main/java/com/facebook/presto/server/protocol/QueuedStatementResource.java
@@ -30,8 +30,8 @@
import com.facebook.presto.server.SessionContext;
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.QueryId;
-import com.facebook.presto.spi.tracing.TracerProvider;
import com.facebook.presto.sql.parser.SqlParserOptions;
+import com.facebook.presto.tracing.TracerProviderManager;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
@@ -125,7 +125,7 @@ public class QueuedStatementResource
private final boolean compressionEnabled;
private final SqlParserOptions sqlParserOptions;
- private final TracerProvider tracerProvider;
+ private final TracerProviderManager tracerProviderManager;
private final SessionPropertyManager sessionPropertyManager; // We may need some system default session property values at early query stage even before session is created.
private final QueryBlockingRateLimiter queryRateLimiter;
@@ -138,7 +138,7 @@ public QueuedStatementResource(
LocalQueryProvider queryResultsProvider,
SqlParserOptions sqlParserOptions,
ServerConfig serverConfig,
- TracerProvider tracerProvider,
+ TracerProviderManager tracerProviderManager,
SessionPropertyManager sessionPropertyManager,
QueryBlockingRateLimiter queryRateLimiter)
{
@@ -149,7 +149,7 @@ public QueuedStatementResource(
this.responseExecutor = requireNonNull(executor, "responseExecutor is null").getExecutor();
this.timeoutExecutor = requireNonNull(executor, "timeoutExecutor is null").getScheduledExecutor();
- this.tracerProvider = requireNonNull(tracerProvider, "tracerProvider is null");
+ this.tracerProviderManager = requireNonNull(tracerProviderManager, "tracerProviderManager is null");
this.sessionPropertyManager = sessionPropertyManager;
this.queryRateLimiter = requireNonNull(queryRateLimiter, "queryRateLimiter is null");
@@ -215,7 +215,7 @@ public Response postStatement(
SessionContext sessionContext = new HttpRequestSessionContext(
servletRequest,
sqlParserOptions,
- tracerProvider,
+ tracerProviderManager.getTracerProvider(),
Optional.of(sessionPropertyManager));
Query query = new Query(statement, sessionContext, dispatchManager, queryResultsProvider, 0);
queries.put(query.getQueryId(), query);
diff --git a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java
index 45b0330aa4115..15921db08084a 100644
--- a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java
+++ b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java
@@ -201,6 +201,7 @@
import com.facebook.presto.sql.tree.Statement;
import com.facebook.presto.sql.tree.TruncateTable;
import com.facebook.presto.testing.PageConsumerOperator.PageConsumerOutputFactory;
+import com.facebook.presto.tracing.TracerProviderManager;
import com.facebook.presto.tracing.TracingConfig;
import com.facebook.presto.transaction.InMemoryTransactionManager;
import com.facebook.presto.transaction.TransactionManager;
@@ -480,7 +481,8 @@ private LocalQueryRunner(Session defaultSession, FeaturesConfig featuresConfig,
new SessionPropertyDefaults(nodeInfo),
new ThrowingNodeTtlFetcherManager(),
new ThrowingClusterTtlProviderManager(),
- historyBasedPlanStatisticsManager);
+ historyBasedPlanStatisticsManager,
+ new TracerProviderManager(new TracingConfig()));
connectorManager.addConnectorFactory(globalSystemConnectorFactory);
connectorManager.createConnection(GlobalSystemConnector.NAME, GlobalSystemConnector.NAME, ImmutableMap.of());
diff --git a/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerHandle.java b/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerHandle.java
new file mode 100644
index 0000000000000..a182bf535b419
--- /dev/null
+++ b/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerHandle.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.facebook.presto.tracing;
+
+import com.facebook.presto.spi.tracing.TracerHandle;
+
+public class NoopTracerHandle
+ implements TracerHandle
+{
+ private final String traceToken;
+
+ public NoopTracerHandle()
+ {
+ this.traceToken = "noop_dummy_id";
+ }
+
+ @Override
+ public String getTraceToken()
+ {
+ return traceToken;
+ }
+}
diff --git a/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerProvider.java b/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerProvider.java
index ef2918e6e455a..44bc11d4c2424 100644
--- a/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerProvider.java
+++ b/presto-main/src/main/java/com/facebook/presto/tracing/NoopTracerProvider.java
@@ -15,19 +15,44 @@
import com.facebook.presto.spi.tracing.NoopTracer;
import com.facebook.presto.spi.tracing.Tracer;
+import com.facebook.presto.spi.tracing.TracerHandle;
import com.facebook.presto.spi.tracing.TracerProvider;
import com.google.inject.Inject;
+import java.util.Map;
+import java.util.function.Function;
+
public class NoopTracerProvider
implements TracerProvider
{
public static final NoopTracerProvider NOOP_TRACER_PROVIDER = new NoopTracerProvider();
public static final NoopTracer NOOP_TRACER = new NoopTracer();
+ public static final TracerHandle NOOP_TRACER_HANDLE = new NoopTracerHandle();
+ public static final Function