You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by st...@apache.org on 2023/08/17 12:54:57 UTC
[solr] branch main updated: SOLR-16536 Replace OpenTracing instrumentation with OpenTelemetry (#1841)
This is an automated email from the ASF dual-hosted git repository.
stillalex pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 92dede18504 SOLR-16536 Replace OpenTracing instrumentation with OpenTelemetry (#1841)
92dede18504 is described below
commit 92dede18504518a5542ddd35b0d9cc2887566934
Author: Alex D <st...@apache.org>
AuthorDate: Thu Aug 17 05:54:52 2023 -0700
SOLR-16536 Replace OpenTracing instrumentation with OpenTelemetry (#1841)
OpenTracing libraries were completely removed and replaced with OpenTelemetry libraries
---
solr/CHANGES.txt | 2 +
solr/core/build.gradle | 6 +-
.../src/java/org/apache/solr/api/AnnotatedApi.java | 2 +-
solr/core/src/java/org/apache/solr/api/Api.java | 2 +-
.../src/java/org/apache/solr/api/V2HttpCall.java | 10 +-
.../java/org/apache/solr/core/CoreContainer.java | 10 +-
.../org/apache/solr/core/TracerConfigurator.java | 80 +-------
.../handler/admin/api/RestoreCollectionAPI.java | 2 +-
.../solr/handler/component/HttpShardHandler.java | 12 +-
.../solr/handler/component/ShardRequest.java | 5 -
.../solr/request/DelegatingSolrQueryRequest.java | 8 +-
.../org/apache/solr/request/SolrQueryRequest.java | 22 +--
.../apache/solr/request/SolrQueryRequestBase.java | 32 ----
.../java/org/apache/solr/servlet/HttpSolrCall.java | 22 +--
.../java/org/apache/solr/servlet/ServletUtils.java | 49 ++---
.../apache/solr/servlet/SolrDispatchFilter.java | 27 +--
.../org/apache/solr/update/SolrCmdDistributor.java | 13 +-
.../java/org/apache/solr/update/UpdateCommand.java | 16 +-
.../solr/util/tracing/HttpServletCarrier.java | 92 ----------
...tCarrier.java => HttpServletRequestGetter.java} | 35 ++--
...rRequestCarrier.java => SolrRequestSetter.java} | 25 +--
.../org/apache/solr/util/tracing/TraceUtils.java | 116 +++++++++++-
.../admin/api/AddReplicaPropertyAPITest.java | 4 +-
.../handler/admin/api/CoreReplicationAPITest.java | 4 +-
.../solr/handler/admin/api/ListAliasesAPITest.java | 4 +-
...rier.java => TestHttpServletRequestGetter.java} | 50 ++---
.../opentelemetry-opentracing-shim-1.29.0.jar.sha1 | 1 -
.../opentelemetry-sdk-testing-1.29.0.jar.sha1 | 1 +
solr/licenses/opentracing-api-0.33.0.jar.sha1 | 1 -
solr/licenses/opentracing-api-LICENSE-ASL.txt | 201 ---------------------
solr/licenses/opentracing-api-NOTICE.txt | 0
solr/licenses/opentracing-mock-0.33.0.jar.sha1 | 1 -
solr/licenses/opentracing-mock-LICENSE-ASL.txt | 201 ---------------------
solr/licenses/opentracing-mock-NOTICE.txt | 0
solr/licenses/opentracing-noop-0.33.0.jar.sha1 | 1 -
solr/licenses/opentracing-noop-LICENSE-ASL.txt | 201 ---------------------
solr/licenses/opentracing-noop-NOTICE.txt | 0
solr/licenses/opentracing-util-0.33.0.jar.sha1 | 1 -
solr/licenses/opentracing-util-LICENSE-ASL.txt | 201 ---------------------
solr/licenses/opentracing-util-NOTICE.txt | 0
solr/modules/opentelemetry/build.gradle | 14 +-
.../solr/opentelemetry/ClosableTracerShim.java | 85 ---------
.../solr/opentelemetry/OtelTracerConfigurator.java | 38 ++--
.../opentelemetry/src/test-files/solr/solr.xml | 2 +-
.../CustomTestOtelTracerConfigurator.java | 104 +++++++++++
.../opentelemetry/OtelTracerConfiguratorTest.java | 44 +----
.../opentelemetry}/TestDistributedTracing.java | 141 ++++++++-------
.../pages/major-changes-in-solr-10.adoc | 2 +
solr/test-framework/build.gradle | 2 -
.../src/java/org/apache/solr/SolrTestCaseJ4.java | 36 +---
versions.lock | 12 +-
versions.props | 1 -
52 files changed, 469 insertions(+), 1472 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index b82508e9e6b..098080ed7c2 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -17,6 +17,8 @@ Improvements
* SOLR-16800: Solr CLI commands that use -solrUrl now work with a bare url like http://localhost:8983, you no longer need to add the /solr at the end. (Eric Pugh)
+* SOLR-16536: Replace OpenTracing instrumentation with OpenTelemetry (Alex Deparvu, janhoy)
+
Optimizations
---------------------
(No changes)
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index d868164cd75..61ecd1713af 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -141,10 +141,8 @@ dependencies {
implementation 'com.tdunning:t-digest'
// Distributed Tracing
- api 'io.opentracing:opentracing-api' // Tracer is exposed on some methods
- implementation 'io.opentracing:opentracing-noop'
- implementation 'io.opentracing:opentracing-util'
- testImplementation 'io.opentracing:opentracing-mock'
+ api 'io.opentelemetry:opentelemetry-api' // Tracer is exposed on some methods
+ implementation 'io.opentelemetry:opentelemetry-context'
implementation 'org.apache.commons:commons-exec'
diff --git a/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java b/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
index 7ec6ab6a919..bfe35c47108 100644
--- a/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
+++ b/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
@@ -215,7 +215,7 @@ public class AnnotatedApi extends Api implements PermissionNameProvider, Closeab
}
for (CommandOperation cmd : cmds) {
- TraceUtils.ifNotNoop(req.getSpan(), (span) -> span.log("Command: " + cmd.name));
+ TraceUtils.ifNotNoop(req.getSpan(), (span) -> span.addEvent("Command: " + cmd.name));
commands.get(cmd.name).invoke(req, rsp, cmd);
}
diff --git a/solr/core/src/java/org/apache/solr/api/Api.java b/solr/core/src/java/org/apache/solr/api/Api.java
index 54010912ae2..8e881b7f74e 100644
--- a/solr/core/src/java/org/apache/solr/api/Api.java
+++ b/solr/core/src/java/org/apache/solr/api/Api.java
@@ -41,7 +41,7 @@ public abstract class Api implements SpecProvider {
if (commandSchema == null) {
synchronized (this) {
if (commandSchema == null) {
- ValidatingJsonMap commands = getSpec().getMap("commands", null);
+ ValidatingJsonMap commands = spec != null ? getSpec().getMap("commands", null) : null;
commandSchema =
commands != null ? Map.copyOf(ApiBag.getParsedSchema(commands)) : Map.of();
}
diff --git a/solr/core/src/java/org/apache/solr/api/V2HttpCall.java b/solr/core/src/java/org/apache/solr/api/V2HttpCall.java
index 46c66e403df..92008542a60 100644
--- a/solr/core/src/java/org/apache/solr/api/V2HttpCall.java
+++ b/solr/core/src/java/org/apache/solr/api/V2HttpCall.java
@@ -23,8 +23,7 @@ import static org.apache.solr.servlet.SolrDispatchFilter.Action.ADMIN_OR_REMOTEQ
import static org.apache.solr.servlet.SolrDispatchFilter.Action.PROCESS;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.REMOTEQUERY;
-import io.opentracing.Span;
-import io.opentracing.tag.Tags;
+import io.opentelemetry.api.trace.Span;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -65,6 +64,7 @@ import org.apache.solr.servlet.HttpSolrCall;
import org.apache.solr.servlet.SolrDispatchFilter;
import org.apache.solr.servlet.SolrRequestParsers;
import org.apache.solr.servlet.cache.Method;
+import org.apache.solr.util.tracing.TraceUtils;
import org.glassfish.jersey.server.ApplicationHandler;
import org.glassfish.jersey.server.ContainerRequest;
import org.slf4j.Logger;
@@ -499,9 +499,7 @@ public class V2HttpCall extends HttpSolrCall {
coreOrColName = pathTemplateValues.get("core");
}
}
- if (coreOrColName != null) {
- span.setTag(Tags.DB_INSTANCE, coreOrColName);
- }
+ TraceUtils.setDbInstance(span, coreOrColName);
// Get the templatize-ed path, ex: "/c/{collection}"
final String path = computeEndpointPath();
@@ -521,7 +519,7 @@ public class V2HttpCall extends HttpSolrCall {
verb = req.getMethod().toLowerCase(Locale.ROOT);
}
- span.setOperationName(verb + ":" + path);
+ span.updateName(verb + ":" + path);
}
/** Example: /c/collection1/ and template map collection->collection1 produces /c/{collection}. */
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index f223f41e36f..5606d93dc85 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -31,9 +31,7 @@ import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGI
import com.github.benmanes.caffeine.cache.Interner;
import com.google.common.annotations.VisibleForTesting;
-import io.opentracing.Tracer;
-import io.opentracing.noop.NoopTracer;
-import io.opentracing.noop.NoopTracerFactory;
+import io.opentelemetry.api.trace.Tracer;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.Path;
@@ -268,7 +266,7 @@ public class CoreContainer {
protected volatile SolrMetricsContext solrMetricsContext;
- protected volatile Tracer tracer = NoopTracerFactory.create();
+ protected volatile Tracer tracer;
protected MetricsHandler metricsHandler;
@@ -695,7 +693,7 @@ public class CoreContainer {
return metricsHandler;
}
- /** Never null but may implement {@link NoopTracer}. */
+ /** Never null */
public Tracer getTracer() {
return tracer;
}
@@ -1375,8 +1373,6 @@ public class CoreContainer {
org.apache.lucene.util.IOUtils.closeWhileHandlingException(packageLoader);
}
org.apache.lucene.util.IOUtils.closeWhileHandlingException(loader); // best effort
-
- tracer.close();
}
public void cancelCoreRecoveries() {
diff --git a/solr/core/src/java/org/apache/solr/core/TracerConfigurator.java b/solr/core/src/java/org/apache/solr/core/TracerConfigurator.java
index ba36ed127ec..bc1798863f7 100644
--- a/solr/core/src/java/org/apache/solr/core/TracerConfigurator.java
+++ b/solr/core/src/java/org/apache/solr/core/TracerConfigurator.java
@@ -17,83 +17,23 @@
package org.apache.solr.core;
-import io.opentracing.Scope;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.util.GlobalTracer;
-import java.lang.invoke.MethodHandles;
-import java.util.concurrent.atomic.AtomicReference;
-import org.apache.solr.common.util.ExecutorUtil;
+import io.opentelemetry.api.trace.Tracer;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.solr.util.tracing.TraceUtils;
-/** Produces an OpenTracing {@link Tracer} from configuration. */
+/** Produces a {@link Tracer} from configuration. */
public abstract class TracerConfigurator implements NamedListInitializedPlugin {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- public abstract Tracer getTracer();
public static Tracer loadTracer(SolrResourceLoader loader, PluginInfo info) {
- // In "normal" Solr operation, loadTracer is called once in Solr's lifetime.
- // In test mode we run many test suites, sometimes multiple servers per test suite.
- // It's important that the tracing config not change throughout a test suite because of the
- // static singleton pattern and assumptions based on this.
-
if (info != null && info.isEnabled()) {
- GlobalTracer.registerIfAbsent(
- () -> {
- TracerConfigurator configurator =
- loader.newInstance(info.className, TracerConfigurator.class);
- configurator.init(info.initArgs);
- return configurator.getTracer();
- });
- }
- if (GlobalTracer.isRegistered()) {
- // ideally we would furthermore check that it's not a no-op impl either but
- // GlobalTracer.get() always returns a GlobalTracer implementing Tracer that delegates
- // to the real Tracer (that may or may not be a No-Op impl).
- ExecutorUtil.addThreadLocalProvider(new TracerConfigurator.SpanThreadLocalProvider());
+ TracerConfigurator configurator =
+ loader.newInstance(info.className, TracerConfigurator.class);
+ configurator.init(info.initArgs);
+ return configurator.getTracer();
+ } else {
+ return TraceUtils.noop();
}
-
- return GlobalTracer.get();
}
- /**
- * Propagate the active span across threads. New spans are not created, which means that we're
- * possibly exposing a Span to a thread that may find that it has already finished, depending on
- * how the instrumented thread pool is used. It's probably fine to create new spans related to a
- * finished span? It's not okay to otherwise touch a finished span (e.g. to log or tag).
- *
- * <p>This strategy is also used by {@code
- * brave.propagation.CurrentTraceContext#wrap(java.lang.Runnable)}.
- */
- private static class SpanThreadLocalProvider
- implements ExecutorUtil.InheritableThreadLocalProvider {
- private final Tracer tracer = GlobalTracer.get();
-
- @Override
- public void store(AtomicReference<Object> ctx) {
- assert tracer == GlobalTracer.get() : "Tracer changed; not supported!";
- ctx.set(tracer.scopeManager().activeSpan());
- }
-
- @Override
- public void set(AtomicReference<Object> ctx) {
- final Span span = (Span) ctx.get();
- if (span != null) {
- log.trace("Thread received span to do async work: {}", span);
- final Scope scope = tracer.scopeManager().activate(span);
- ctx.set(scope);
- }
- }
-
- @Override
- public void clean(AtomicReference<Object> ctx) {
- Scope scope = (Scope) ctx.get();
- if (scope != null) {
- scope.close();
- }
- }
- }
+ protected abstract Tracer getTracer();
}
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java
index 18caed1933a..1809d83f6b9 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java
@@ -108,8 +108,8 @@ public class RestoreCollectionAPI extends BackupAPIBase {
}
final String collectionName = requestBody.collection;
- recordCollectionForLogAndTracing(collectionName, solrQueryRequest);
SolrIdentifierValidator.validateCollectionName(collectionName);
+ recordCollectionForLogAndTracing(collectionName, solrQueryRequest);
if (coreContainer.getAliases().hasAlias(collectionName)) {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST,
diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java
index 0ad76294335..17fb78a86c6 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java
@@ -16,9 +16,6 @@
*/
package org.apache.solr.handler.component;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.propagation.Format;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -50,7 +47,7 @@ import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.security.AllowListUrlChecker;
-import org.apache.solr.util.tracing.SolrRequestCarrier;
+import org.apache.solr.util.tracing.TraceUtils;
@NotThreadSafe
public class HttpShardHandler extends ShardHandler {
@@ -128,8 +125,6 @@ public class HttpShardHandler extends ShardHandler {
final ShardRequest sreq, final String shard, final ModifiableSolrParams params) {
// do this outside of the callable for thread safety reasons
final List<String> urls = getURLs(shard);
- final Tracer tracer = sreq.tracer; // not null
- final Span span = tracer.activeSpan(); // probably not null?
params.remove(CommonParams.WT); // use default (currently javabin)
params.remove(CommonParams.VERSION);
@@ -171,10 +166,7 @@ public class HttpShardHandler extends ShardHandler {
@Override
public void onStart() {
- if (span != null) {
- tracer.inject(
- span.context(), Format.Builtin.HTTP_HEADERS, new SolrRequestCarrier(req));
- }
+ TraceUtils.injectContextIntoRequest(req);
SolrRequestInfo requestInfo = SolrRequestInfo.getRequestInfo();
if (requestInfo != null)
req.setUserPrincipal(requestInfo.getReq().getUserPrincipal());
diff --git a/solr/core/src/java/org/apache/solr/handler/component/ShardRequest.java b/solr/core/src/java/org/apache/solr/handler/component/ShardRequest.java
index 03b660ff9be..d7d7da04f22 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/ShardRequest.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/ShardRequest.java
@@ -16,8 +16,6 @@
*/
package org.apache.solr.handler.component;
-import io.opentracing.Tracer;
-import io.opentracing.util.GlobalTracer;
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.common.params.ModifiableSolrParams;
@@ -58,9 +56,6 @@ public class ShardRequest {
/** may be null */
public String nodeName;
- /** Not null but may implement {@link io.opentracing.noop.NoopTracer}. */
- public final Tracer tracer = GlobalTracer.get();
-
// TODO: one could store a list of numbers to correlate where returned docs
// go in the top-level response rather than looking up by id...
// this would work well if we ever transitioned to using internal ids and
diff --git a/solr/core/src/java/org/apache/solr/request/DelegatingSolrQueryRequest.java b/solr/core/src/java/org/apache/solr/request/DelegatingSolrQueryRequest.java
index 2c9c20d4f06..158f02cdff3 100644
--- a/solr/core/src/java/org/apache/solr/request/DelegatingSolrQueryRequest.java
+++ b/solr/core/src/java/org/apache/solr/request/DelegatingSolrQueryRequest.java
@@ -16,8 +16,7 @@
*/
package org.apache.solr.request;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.opentelemetry.api.trace.Span;
import java.security.Principal;
import java.util.List;
import java.util.Map;
@@ -150,11 +149,6 @@ public class DelegatingSolrQueryRequest implements SolrQueryRequest {
return delegate.getHttpSolrCall();
}
- @Override
- public Tracer getTracer() {
- return delegate.getTracer();
- }
-
@Override
public Span getSpan() {
return delegate.getSpan();
diff --git a/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java b/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
index 613ae31d438..113aeff6440 100644
--- a/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
+++ b/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
@@ -16,10 +16,7 @@
*/
package org.apache.solr.request;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.noop.NoopSpan;
-import io.opentracing.util.GlobalTracer;
+import io.opentelemetry.api.trace.Span;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
@@ -136,21 +133,16 @@ public interface SolrQueryRequest extends AutoCloseable {
return null;
}
- /**
- * Distributed tracing Tracer. Never null but might implement {@link
- * io.opentracing.noop.NoopTracer}.
- */
- default Tracer getTracer() {
- return GlobalTracer.get(); // default impl is only for some tests
- }
-
/**
* The distributed tracing Span for the request itself; never null. This is useful for adding tags
- * or updating the operation name of the request span. If you need the current span, which might
- * not necessarily be the request span, do this instead: {@code tracer.activeSpan()}.
+ * or updating the operation name of the request span. Not null.
*/
default Span getSpan() {
- return NoopSpan.INSTANCE;
+ final HttpSolrCall call = getHttpSolrCall();
+ if (call != null) {
+ return call.getSpan();
+ }
+ return Span.getInvalid();
}
default CoreContainer getCoreContainer() {
diff --git a/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java b/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
index f1034b00bec..363022c3979 100644
--- a/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
+++ b/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
@@ -16,10 +16,6 @@
*/
package org.apache.solr.request;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.noop.NoopSpan;
-import io.opentracing.util.GlobalTracer;
import java.io.Closeable;
import java.security.Principal;
import java.util.Collections;
@@ -38,7 +34,6 @@ import org.apache.solr.common.util.ValidatingJsonMap;
import org.apache.solr.core.SolrCore;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.search.SolrIndexSearcher;
-import org.apache.solr.servlet.HttpSolrCall;
import org.apache.solr.util.RTimerTree;
import org.apache.solr.util.RefCounted;
@@ -145,33 +140,6 @@ public abstract class SolrQueryRequestBase implements SolrQueryRequest, Closeabl
return schema;
}
- @Override
- public Tracer getTracer() {
- final HttpSolrCall call = getHttpSolrCall();
- if (call != null) {
- final Tracer tracer = (Tracer) call.getReq().getAttribute(Tracer.class.getName());
- if (tracer != null) {
- return tracer;
- }
- }
- if (core != null) {
- return core.getCoreContainer().getTracer();
- }
- return GlobalTracer.get(); // this way is not ideal (particularly in tests) but it's okay
- }
-
- @Override
- public Span getSpan() {
- final HttpSolrCall call = getHttpSolrCall();
- if (call != null) {
- final Span span = (Span) call.getReq().getAttribute(Span.class.getName());
- if (span != null) {
- return span;
- }
- }
- return NoopSpan.INSTANCE;
- }
-
@Override
public void updateSchemaToLatest() {
schema = core.getLatestSchema();
diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
index dbee25ec32f..f1e5a25693c 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -32,8 +32,7 @@ import static org.apache.solr.servlet.SolrDispatchFilter.Action.REMOTEQUERY;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.RETRY;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.RETURN;
-import io.opentracing.Span;
-import io.opentracing.tag.Tags;
+import io.opentelemetry.api.trace.Span;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -50,7 +49,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -626,10 +624,14 @@ public class HttpSolrCall {
"handleOrForwardRequest should not be invoked when serving v1 requests.");
}
- /** Get the span for this request. Not null. */
- protected Span getSpan() {
- // Span was put into the request by SolrDispatchFilter
- return (Span) Objects.requireNonNull(req.getAttribute(Span.class.getName()));
+ /** Get the Span for this request. Not null. */
+ public Span getSpan() {
+ var s = TraceUtils.getSpan(req);
+ if (s != null) {
+ return s;
+ } else {
+ return Span.getInvalid();
+ }
}
// called after init().
@@ -639,9 +641,7 @@ public class HttpSolrCall {
if (coreOrColName == null && getCore() != null) {
coreOrColName = getCore().getName();
}
- if (coreOrColName != null) {
- span.setTag(Tags.DB_INSTANCE, coreOrColName);
- }
+ TraceUtils.setDbInstance(span, coreOrColName);
// Set operation name.
String path = getPath();
@@ -655,7 +655,7 @@ public class HttpSolrCall {
}
String verb =
getQueryParams().get(CoreAdminParams.ACTION, req.getMethod()).toLowerCase(Locale.ROOT);
- span.setOperationName(verb + ":" + path);
+ span.updateName(verb + ":" + path);
}
public boolean shouldAudit() {
diff --git a/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java b/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java
index a286078dafb..5297fe44401 100644
--- a/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java
+++ b/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java
@@ -17,12 +17,8 @@
package org.apache.solr.servlet;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.noop.NoopSpan;
-import io.opentracing.noop.NoopTracer;
-import io.opentracing.propagation.Format;
-import io.opentracing.tag.Tags;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Context;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -45,7 +41,7 @@ import org.apache.http.HttpHeaders;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.logging.MDCLoggingContext;
-import org.apache.solr.util.tracing.HttpServletCarrier;
+import org.apache.solr.util.tracing.TraceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -234,15 +230,14 @@ public abstract class ServletUtils {
private static void traceHttpRequestExecution2(
HttpServletRequest request, HttpServletResponse response, Runnable tracedExecution)
throws ServletException, IOException {
- Tracer tracer = getTracer(request);
- Span span = buildSpan(tracer, request);
-
- request.setAttribute(SolrDispatchFilter.ATTR_TRACING_SPAN, span);
- try (var scope = tracer.scopeManager().activate(span)) {
+ Context context = TraceUtils.extractContext(request);
+ Span span = TraceUtils.startHttpRequestSpan(request, context);
+ try (var scope = context.with(span).makeCurrent()) {
assert scope != null; // prevent javac warning about scope being unused
- MDCLoggingContext.setTracerId(span.context().toTraceId()); // handles empty string
-
+ TraceUtils.setSpan(request, span);
+ TraceUtils.ifNotNoop(
+ span, s -> MDCLoggingContext.setTracerId(s.getSpanContext().getTraceId()));
tracedExecution.run();
} catch (ExceptionWhileTracing e) {
if (e.e instanceof SolrAuthenticationException) {
@@ -261,31 +256,9 @@ public abstract class ServletUtils {
throw new RuntimeException(e.e);
}
} finally {
- span.setTag(Tags.HTTP_STATUS, response.getStatus());
- span.finish();
- }
- }
-
- private static Tracer getTracer(HttpServletRequest req) {
- return (Tracer) req.getAttribute(SolrDispatchFilter.ATTR_TRACING_TRACER);
- }
-
- protected static Span buildSpan(Tracer tracer, HttpServletRequest request) {
- if (tracer instanceof NoopTracer) {
- return NoopSpan.INSTANCE;
- }
- Tracer.SpanBuilder spanBuilder =
- tracer
- .buildSpan("http.request") // will be changed later
- .asChildOf(tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpServletCarrier(request)))
- .withTag(Tags.SPAN_KIND, Tags.SPAN_KIND_SERVER)
- .withTag(Tags.HTTP_METHOD, request.getMethod())
- .withTag(Tags.HTTP_URL, request.getRequestURL().toString());
- if (request.getQueryString() != null) {
- spanBuilder.withTag("http.params", request.getQueryString());
+ TraceUtils.setHttpStatus(span, response.getStatus());
+ span.end();
}
- spanBuilder.withTag(Tags.DB_TYPE, "solr");
- return spanBuilder.start();
}
// we make sure we read the full client request so that the client does
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
index cfd9836c4ed..7b9c2b7e90c 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
@@ -16,16 +16,13 @@
*/
package org.apache.solr.servlet;
-import static org.apache.solr.security.AuditEvent.EventType;
import static org.apache.solr.servlet.ServletUtils.closeShield;
import static org.apache.solr.servlet.ServletUtils.configExcludes;
import static org.apache.solr.servlet.ServletUtils.excludedPath;
+import static org.apache.solr.util.tracing.TraceUtils.getSpan;
+import static org.apache.solr.util.tracing.TraceUtils.setTracer;
import com.google.common.annotations.VisibleForTesting;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.tag.Tags;
-import io.opentracing.util.GlobalTracer;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.List;
@@ -54,10 +51,12 @@ import org.apache.solr.logging.MDCLoggingContext;
import org.apache.solr.logging.MDCSnapshot;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.security.AuditEvent;
+import org.apache.solr.security.AuditEvent.EventType;
import org.apache.solr.security.AuthenticationPlugin;
import org.apache.solr.security.PKIAuthenticationPlugin;
import org.apache.solr.security.PublicKeyHandler;
import org.apache.solr.servlet.CoreContainerProvider.ServiceHolder;
+import org.apache.solr.util.tracing.TraceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,8 +72,6 @@ import org.slf4j.LoggerFactory;
// things like CoreContainer can be requested. (or better yet injected)
public class SolrDispatchFilter extends BaseSolrFilter implements PathExcluder {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- public static final String ATTR_TRACING_SPAN = Span.class.getName();
- public static final String ATTR_TRACING_TRACER = Tracer.class.getName();
// TODO: see if we can get rid of the holder here (Servlet spec actually guarantees
// ContextListeners run before filter init, but JettySolrRunner that we use for tests is
@@ -206,8 +203,7 @@ public class SolrDispatchFilter extends BaseSolrFilter implements PathExcluder {
if (excludedPath(excludePatterns, request, response, chain)) {
return;
}
- Tracer t = getCores() == null ? GlobalTracer.get() : getCores().getTracer();
- request.setAttribute(ATTR_TRACING_TRACER, t);
+ setTracer(request, getCores().getTracer());
RateLimitManager rateLimitManager = coreService.getService().getRateLimitManager();
try {
ServletUtils.rateLimitRequest(
@@ -228,10 +224,6 @@ public class SolrDispatchFilter extends BaseSolrFilter implements PathExcluder {
}
}
- private static Span getSpan(HttpServletRequest req) {
- return (Span) req.getAttribute(ATTR_TRACING_SPAN);
- }
-
private void dispatch(
FilterChain chain, HttpServletRequest request, HttpServletResponse response, boolean retry)
throws IOException, ServletException, SolrAuthenticationException {
@@ -242,11 +234,12 @@ public class SolrDispatchFilter extends BaseSolrFilter implements PathExcluder {
request = wrappedRequest.get();
}
+ var span = getSpan(request);
if (getCores().getAuthenticationPlugin() != null) {
if (log.isDebugEnabled()) {
log.debug("User principal: {}", request.getUserPrincipal());
}
- getSpan(request).setTag(Tags.DB_USER, String.valueOf(request.getUserPrincipal()));
+ TraceUtils.setUser(span, String.valueOf(request.getUserPrincipal()));
}
HttpSolrCall call = getHttpSolrCall(request, response, retry);
@@ -255,15 +248,15 @@ public class SolrDispatchFilter extends BaseSolrFilter implements PathExcluder {
Action result = call.call();
switch (result) {
case PASSTHROUGH:
- getSpan(request).log("SolrDispatchFilter PASSTHROUGH");
+ span.addEvent("SolrDispatchFilter PASSTHROUGH");
chain.doFilter(request, response);
break;
case RETRY:
- getSpan(request).log("SolrDispatchFilter RETRY");
+ span.addEvent("SolrDispatchFilter RETRY");
doFilter(request, response, chain, true); // RECURSION
break;
case FORWARD:
- getSpan(request).log("SolrDispatchFilter FORWARD");
+ span.addEvent("SolrDispatchFilter FORWARD");
request.getRequestDispatcher(call.getPath()).forward(request, response);
break;
case ADMIN:
diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java
index b7687d4eb1b..b40c79a166f 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java
@@ -16,9 +16,6 @@
*/
package org.apache.solr.update;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
-import io.opentracing.propagation.Format;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@@ -52,7 +49,7 @@ import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.update.processor.DistributedUpdateProcessor;
import org.apache.solr.update.processor.DistributedUpdateProcessor.LeaderRequestReplicationTracker;
import org.apache.solr.update.processor.DistributedUpdateProcessor.RollupRequestReplicationTracker;
-import org.apache.solr.util.tracing.SolrRequestCarrier;
+import org.apache.solr.util.tracing.TraceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -314,13 +311,7 @@ public class SolrCmdDistributor implements Closeable {
if (SolrRequestInfo.getRequestInfo() != null) {
req.uReq.setUserPrincipal(SolrRequestInfo.getRequestInfo().getReq().getUserPrincipal());
}
-
- Tracer tracer = req.cmd.getTracer();
- Span parentSpan = tracer.activeSpan();
- if (parentSpan != null) {
- tracer.inject(
- parentSpan.context(), Format.Builtin.HTTP_HEADERS, new SolrRequestCarrier(req.uReq));
- }
+ TraceUtils.injectContextIntoRequest(req.uReq);
if (req.synchronous) {
blockAndDoRetries();
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateCommand.java b/solr/core/src/java/org/apache/solr/update/UpdateCommand.java
index 9714d712dae..79bbda1f3d3 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateCommand.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateCommand.java
@@ -16,13 +16,11 @@
*/
package org.apache.solr.update;
-import io.opentracing.Tracer;
-import io.opentracing.util.GlobalTracer;
import org.apache.solr.request.SolrQueryRequest;
/** An index update command encapsulated in an object (Command pattern) */
public abstract class UpdateCommand implements Cloneable {
- protected SolrQueryRequest req;
+ protected final SolrQueryRequest req;
protected long version;
protected String route;
protected int flags;
@@ -91,18 +89,6 @@ public abstract class UpdateCommand implements Cloneable {
return req;
}
- public void setReq(SolrQueryRequest req) {
- this.req = req;
- }
-
- /**
- * Distributed tracing Tracer. Never null but might implement {@link
- * io.opentracing.noop.NoopTracer}.
- */
- public Tracer getTracer() {
- return (req != null) ? req.getTracer() : GlobalTracer.get();
- }
-
@Override
public UpdateCommand clone() {
try {
diff --git a/solr/core/src/java/org/apache/solr/util/tracing/HttpServletCarrier.java b/solr/core/src/java/org/apache/solr/util/tracing/HttpServletCarrier.java
deleted file mode 100644
index 21ce05e29d1..00000000000
--- a/solr/core/src/java/org/apache/solr/util/tracing/HttpServletCarrier.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.solr.util.tracing;
-
-import io.opentracing.propagation.TextMap;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import javax.servlet.http.HttpServletRequest;
-
-/** A Carrier for extract Span context out of request headers */
-public class HttpServletCarrier implements TextMap {
- private Iterator<Map.Entry<String, String>> it;
-
- public HttpServletCarrier(HttpServletRequest request) {
- this.it =
- new Iterator<>() {
-
- Enumeration<String> headerNameIt = request.getHeaderNames();
- String headerName = null;
- Enumeration<String> headerValue = null;
-
- @Override
- public boolean hasNext() {
- if (headerValue != null && headerValue.hasMoreElements()) {
- return true;
- }
-
- return headerNameIt.hasMoreElements();
- }
-
- @Override
- public Map.Entry<String, String> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
-
- if (headerValue == null || !headerValue.hasMoreElements()) {
- headerName = headerNameIt.nextElement();
- headerValue = request.getHeaders(headerName);
- }
-
- String key = headerName;
- String val = headerValue.nextElement();
-
- return new Map.Entry<>() {
- @Override
- public String getKey() {
- return key;
- }
-
- @Override
- public String getValue() {
- return val;
- }
-
- @Override
- public String setValue(String value) {
- throw new UnsupportedOperationException();
- }
- };
- }
- };
- }
-
- @Override
- public Iterator<Map.Entry<String, String>> iterator() {
- return it;
- }
-
- @Override
- public void put(String key, String value) {
- throw new UnsupportedOperationException(
- "HttpServletCarrier should only be used with Tracer.extract()");
- }
-}
diff --git a/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java b/solr/core/src/java/org/apache/solr/util/tracing/HttpServletRequestGetter.java
similarity index 56%
copy from solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java
copy to solr/core/src/java/org/apache/solr/util/tracing/HttpServletRequestGetter.java
index 6f4917e1b8f..f2756566ed9 100644
--- a/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java
+++ b/solr/core/src/java/org/apache/solr/util/tracing/HttpServletRequestGetter.java
@@ -14,30 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.solr.util.tracing;
-import io.opentracing.propagation.TextMap;
+import io.opentelemetry.context.propagation.TextMapGetter;
import java.util.Iterator;
-import java.util.Map;
-import org.apache.solr.client.solrj.SolrRequest;
-
-/** An OpenTracing Carrier for injecting Span context through SolrRequest */
-public class SolrRequestCarrier implements TextMap {
-
- private final SolrRequest<?> solrRequest;
+import javax.servlet.http.HttpServletRequest;
- public SolrRequestCarrier(SolrRequest<?> solrRequest) {
- this.solrRequest = solrRequest;
- }
+/**
+ * {@code HttpServletRequest} aware {@code TextMapGetter} that allows header data to be extracted
+ * from a request
+ */
+public class HttpServletRequestGetter implements TextMapGetter<HttpServletRequest> {
@Override
- public Iterator<Map.Entry<String, String>> iterator() {
- throw new UnsupportedOperationException("carrier is write-only");
+ public Iterable<String> keys(HttpServletRequest carrier) {
+ return new Iterable<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return carrier.getHeaderNames().asIterator();
+ }
+ };
}
@Override
- public void put(String key, String value) {
- solrRequest.addHeader(key, value);
+ public String get(HttpServletRequest carrier, String key) {
+ if (carrier == null) {
+ return null;
+ }
+ return carrier.getHeader(key);
}
}
diff --git a/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java b/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestSetter.java
similarity index 60%
rename from solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java
rename to solr/core/src/java/org/apache/solr/util/tracing/SolrRequestSetter.java
index 6f4917e1b8f..0923d9db014 100644
--- a/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestCarrier.java
+++ b/solr/core/src/java/org/apache/solr/util/tracing/SolrRequestSetter.java
@@ -17,27 +17,16 @@
package org.apache.solr.util.tracing;
-import io.opentracing.propagation.TextMap;
-import java.util.Iterator;
-import java.util.Map;
+import io.opentelemetry.context.propagation.TextMapSetter;
import org.apache.solr.client.solrj.SolrRequest;
-/** An OpenTracing Carrier for injecting Span context through SolrRequest */
-public class SolrRequestCarrier implements TextMap {
-
- private final SolrRequest<?> solrRequest;
-
- public SolrRequestCarrier(SolrRequest<?> solrRequest) {
- this.solrRequest = solrRequest;
- }
-
- @Override
- public Iterator<Map.Entry<String, String>> iterator() {
- throw new UnsupportedOperationException("carrier is write-only");
- }
+/**
+ * {@code SolrRequest} aware {@code TextMapSetter} that allows header data to be added to a request
+ */
+public class SolrRequestSetter implements TextMapSetter<SolrRequest<?>> {
@Override
- public void put(String key, String value) {
- solrRequest.addHeader(key, value);
+ public void set(SolrRequest<?> request, String key, String value) {
+ request.addHeader(key, value);
}
}
diff --git a/solr/core/src/java/org/apache/solr/util/tracing/TraceUtils.java b/solr/core/src/java/org/apache/solr/util/tracing/TraceUtils.java
index c7d2f0f0fd9..3505f4daac6 100644
--- a/solr/core/src/java/org/apache/solr/util/tracing/TraceUtils.java
+++ b/solr/core/src/java/org/apache/solr/util/tracing/TraceUtils.java
@@ -16,24 +16,128 @@
*/
package org.apache.solr.util.tracing;
-import io.opentracing.Span;
-import io.opentracing.noop.NoopSpan;
-import io.opentracing.tag.Tags;
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanBuilder;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.propagation.TextMapPropagator;
import java.util.function.Consumer;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.request.SolrQueryRequest;
/** Utilities for distributed tracing. */
public class TraceUtils {
+ private static final String REQ_ATTR_TRACING_SPAN = Span.class.getName();
+ private static final String REQ_ATTR_TRACING_TRACER = Tracer.class.getName();
+ private static final Tracer NOOP_TRACER = TracerProvider.noop().get(null);
+
+ public static final String DEFAULT_SPAN_NAME = "http.request";
+ public static final String WRITE_QUERY_RESPONSE_SPAN_NAME = "writeQueryResponse";
+
+ public static final AttributeKey<String> TAG_DB = AttributeKey.stringKey("db.instance");
+ public static final AttributeKey<String> TAG_DB_TYPE = AttributeKey.stringKey("db.type");
+ public static final AttributeKey<String> TAG_USER = AttributeKey.stringKey("db.user");
+ public static final AttributeKey<Long> TAG_HTTP_STATUS =
+ AttributeKey.longKey("http.response.status_code");
+ public static final AttributeKey<String> TAG_HTTP_METHOD =
+ AttributeKey.stringKey("http.request.method");
+ public static final AttributeKey<String> TAG_HTTP_URL = AttributeKey.stringKey("http.url");
+ public static final AttributeKey<String> TAG_HTTP_PARAMS = AttributeKey.stringKey("http.params");
+ public static final AttributeKey<String> TAG_RESPONSE_WRITER =
+ AttributeKey.stringKey("responseWriter");
+ public static final AttributeKey<String> TAG_CONTENT_TYPE = AttributeKey.stringKey("contentType");
+
+ @Deprecated
+ private static final AttributeKey<String> TAG_HTTP_METHOD_DEP =
+ AttributeKey.stringKey("http.method");
+
+ @Deprecated
+ private static final AttributeKey<Long> TAG_HTTP_STATUS_DEP =
+ AttributeKey.longKey("http.status_code");
+
+ public static final String TAG_DB_TYPE_SOLR = "solr";
+
+ public static Tracer noop() {
+ return NOOP_TRACER;
+ }
+
+ public static TextMapPropagator getTextMapPropagator() {
+ return GlobalOpenTelemetry.getPropagators().getTextMapPropagator();
+ }
+
public static void setDbInstance(SolrQueryRequest req, String coreOrColl) {
- if (req != null && coreOrColl != null) {
- ifNotNoop(req.getSpan(), (span) -> span.setTag(Tags.DB_INSTANCE, coreOrColl));
+ if (req != null) {
+ setDbInstance(req.getSpan(), coreOrColl);
+ }
+ }
+
+ public static void setDbInstance(Span span, String coreOrColName) {
+ if (coreOrColName != null) {
+ span.setAttribute(TAG_DB, coreOrColName);
}
}
+ public static void setUser(Span span, String user) {
+ span.setAttribute(TAG_USER, user);
+ }
+
+ public static void setHttpStatus(Span span, int httpStatus) {
+ span.setAttribute(TAG_HTTP_STATUS, httpStatus);
+ span.setAttribute(TAG_HTTP_STATUS_DEP, httpStatus);
+ }
+
public static void ifNotNoop(Span span, Consumer<Span> consumer) {
- if (span != null && !(span instanceof NoopSpan)) {
+ if (span.isRecording()) {
consumer.accept(span);
}
}
+
+ public static void setSpan(HttpServletRequest req, Span span) {
+ req.setAttribute(REQ_ATTR_TRACING_SPAN, span);
+ }
+
+ public static Span getSpan(HttpServletRequest req) {
+ return (Span) req.getAttribute(REQ_ATTR_TRACING_SPAN);
+ }
+
+ public static void setTracer(HttpServletRequest req, Tracer t) {
+ req.setAttribute(REQ_ATTR_TRACING_TRACER, t);
+ }
+
+ public static Tracer getTracer(HttpServletRequest req) {
+ return (Tracer) req.getAttribute(REQ_ATTR_TRACING_TRACER);
+ }
+
+ public static Context extractContext(HttpServletRequest req) {
+ TextMapPropagator textMapPropagator = getTextMapPropagator();
+ return textMapPropagator.extract(Context.current(), req, new HttpServletRequestGetter());
+ }
+
+ public static void injectContextIntoRequest(SolrRequest<?> req) {
+ TextMapPropagator textMapPropagator = getTextMapPropagator();
+ textMapPropagator.inject(Context.current(), req, new SolrRequestSetter());
+ }
+
+ public static Span startHttpRequestSpan(HttpServletRequest request, Context context) {
+ Tracer tracer = getTracer(request);
+ SpanBuilder spanBuilder =
+ tracer
+ .spanBuilder(DEFAULT_SPAN_NAME) // will be changed later
+ .setParent(context)
+ .setSpanKind(SpanKind.SERVER)
+ .setAttribute(TAG_HTTP_METHOD, request.getMethod())
+ .setAttribute(TAG_HTTP_METHOD_DEP, request.getMethod())
+ .setAttribute(TAG_HTTP_URL, request.getRequestURL().toString());
+ if (request.getQueryString() != null) {
+ spanBuilder.setAttribute(TAG_HTTP_PARAMS, request.getQueryString());
+ }
+ spanBuilder.setAttribute(TAG_DB_TYPE, TAG_DB_TYPE_SOLR);
+ return spanBuilder.startSpan();
+ }
}
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java
index 501d22b130c..6de9c823536 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java
@@ -24,7 +24,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import io.opentracing.noop.NoopSpan;
+import io.opentelemetry.api.trace.Span;
import java.util.Map;
import java.util.Optional;
import org.apache.solr.SolrTestCaseJ4;
@@ -73,7 +73,7 @@ public class AddReplicaPropertyAPITest extends SolrTestCaseJ4 {
when(mockCommandRunner.runCollectionCommand(any(), any(), anyLong()))
.thenReturn(new OverseerSolrResponse(new NamedList<>()));
mockQueryRequest = mock(SolrQueryRequest.class);
- when(mockQueryRequest.getSpan()).thenReturn(NoopSpan.INSTANCE);
+ when(mockQueryRequest.getSpan()).thenReturn(Span.getInvalid());
queryResponse = new SolrQueryResponse();
messageCapturer = ArgumentCaptor.forClass(ZkNodeProps.class);
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java
index 19fd1ea96e2..e6fe9edad0b 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CoreReplicationAPITest.java
@@ -20,7 +20,7 @@ package org.apache.solr.handler.admin.api;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import io.opentracing.noop.NoopSpan;
+import io.opentelemetry.api.trace.Span;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -53,7 +53,7 @@ public class CoreReplicationAPITest extends SolrTestCaseJ4 {
super.setUp();
setUpMocks();
mockQueryRequest = mock(SolrQueryRequest.class);
- when(mockQueryRequest.getSpan()).thenReturn(NoopSpan.INSTANCE);
+ when(mockQueryRequest.getSpan()).thenReturn(Span.getInvalid());
queryResponse = new SolrQueryResponse();
coreReplicationAPI = new CoreReplicationAPIMock(mockCore, mockQueryRequest, queryResponse);
}
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/ListAliasesAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/ListAliasesAPITest.java
index 4cb4d065e36..2a6607c40b6 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/api/ListAliasesAPITest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/api/ListAliasesAPITest.java
@@ -19,7 +19,7 @@ package org.apache.solr.handler.admin.api;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import io.opentracing.noop.NoopSpan;
+import io.opentelemetry.api.trace.Span;
import java.util.List;
import java.util.Map;
import org.apache.solr.SolrTestCaseJ4;
@@ -67,7 +67,7 @@ public class ListAliasesAPITest extends SolrTestCaseJ4 {
when(mockCoreContainer.getZkController()).thenReturn(zkController);
mockQueryRequest = mock(SolrQueryRequest.class);
- when(mockQueryRequest.getSpan()).thenReturn(NoopSpan.INSTANCE);
+ when(mockQueryRequest.getSpan()).thenReturn(Span.getInvalid());
queryResponse = new SolrQueryResponse();
getAliasesAPI = new ListAliasesAPI(mockCoreContainer, mockQueryRequest, queryResponse);
diff --git a/solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletCarrier.java b/solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletRequestGetter.java
similarity index 54%
rename from solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletCarrier.java
rename to solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletRequestGetter.java
index 4001af36b1c..d2b5fdf9bbb 100644
--- a/solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletCarrier.java
+++ b/solr/core/src/test/org/apache/solr/util/tracing/TestHttpServletRequestGetter.java
@@ -17,10 +17,6 @@
package org.apache.solr.util.tracing;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -29,37 +25,43 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
-import org.apache.solr.SolrTestCaseJ4;
+import javax.servlet.http.HttpServletRequestWrapper;
+import org.apache.solr.SolrTestCase;
+import org.eclipse.jetty.server.Request;
import org.junit.Test;
-import org.mockito.stubbing.Answer;
-public class TestHttpServletCarrier extends SolrTestCaseJ4 {
+public class TestHttpServletRequestGetter extends SolrTestCase {
@Test
public void test() {
- SolrTestCaseJ4.assumeWorkingMockito();
- HttpServletRequest req = mock(HttpServletRequest.class);
Map<String, Set<String>> headers =
Map.of(
- "a", Set.of("a", "b", "c"),
- "b", Set.of("a", "b"),
- "c", Set.of("a"));
+ "a", Set.of("0"),
+ "b", Set.of("1"),
+ "c", Set.of("2"));
+
+ HttpServletRequest req =
+ new HttpServletRequestWrapper(new Request(null, null)) {
+
+ @Override
+ public String getHeader(String name) {
+ return headers.get(name).iterator().next();
+ }
- when(req.getHeaderNames()).thenReturn(Collections.enumeration(headers.keySet()));
- when(req.getHeaders(anyString()))
- .thenAnswer(
- (Answer<Enumeration<String>>)
- inv -> {
- String key = inv.getArgument(0);
- return Collections.enumeration(headers.get(key));
- });
+ @Override
+ public Enumeration<String> getHeaderNames() {
+ return Collections.enumeration(headers.keySet());
+ }
+ };
- HttpServletCarrier servletCarrier = new HttpServletCarrier(req);
- Iterator<Map.Entry<String, String>> it = servletCarrier.iterator();
+ HttpServletRequestGetter httpServletRequestGetter = new HttpServletRequestGetter();
+ Iterator<String> it = httpServletRequestGetter.keys(req).iterator();
Map<String, Set<String>> resultBack = new HashMap<>();
while (it.hasNext()) {
- Map.Entry<String, String> entry = it.next();
- resultBack.computeIfAbsent(entry.getKey(), k -> new HashSet<>()).add(entry.getValue());
+ String key = it.next();
+ resultBack
+ .computeIfAbsent(key, k -> new HashSet<>())
+ .add(httpServletRequestGetter.get(req, key));
}
assertEquals(headers, resultBack);
}
diff --git a/solr/licenses/opentelemetry-opentracing-shim-1.29.0.jar.sha1 b/solr/licenses/opentelemetry-opentracing-shim-1.29.0.jar.sha1
deleted file mode 100644
index 1d378f65bc4..00000000000
--- a/solr/licenses/opentelemetry-opentracing-shim-1.29.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-cbe64aea8ea3811911bf6e572f96ec0bc745948d
diff --git a/solr/licenses/opentelemetry-sdk-testing-1.29.0.jar.sha1 b/solr/licenses/opentelemetry-sdk-testing-1.29.0.jar.sha1
new file mode 100644
index 00000000000..87fa435be2c
--- /dev/null
+++ b/solr/licenses/opentelemetry-sdk-testing-1.29.0.jar.sha1
@@ -0,0 +1 @@
+3f36cd924e7631a6888d2280a3b368b3dce3acfc
diff --git a/solr/licenses/opentracing-api-0.33.0.jar.sha1 b/solr/licenses/opentracing-api-0.33.0.jar.sha1
deleted file mode 100644
index c7b2aafb365..00000000000
--- a/solr/licenses/opentracing-api-0.33.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-67336cfb9d93779c02e1fda4c87801d352720eda
diff --git a/solr/licenses/opentracing-api-LICENSE-ASL.txt b/solr/licenses/opentracing-api-LICENSE-ASL.txt
deleted file mode 100644
index 261eeb9e9f8..00000000000
--- a/solr/licenses/opentracing-api-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/solr/licenses/opentracing-api-NOTICE.txt b/solr/licenses/opentracing-api-NOTICE.txt
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/solr/licenses/opentracing-mock-0.33.0.jar.sha1 b/solr/licenses/opentracing-mock-0.33.0.jar.sha1
deleted file mode 100644
index 684a6c3d912..00000000000
--- a/solr/licenses/opentracing-mock-0.33.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-68f907743a5b355a8e975fdd3df0d2e106bbad6c
diff --git a/solr/licenses/opentracing-mock-LICENSE-ASL.txt b/solr/licenses/opentracing-mock-LICENSE-ASL.txt
deleted file mode 100644
index 261eeb9e9f8..00000000000
--- a/solr/licenses/opentracing-mock-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/solr/licenses/opentracing-mock-NOTICE.txt b/solr/licenses/opentracing-mock-NOTICE.txt
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/solr/licenses/opentracing-noop-0.33.0.jar.sha1 b/solr/licenses/opentracing-noop-0.33.0.jar.sha1
deleted file mode 100644
index ea4e70775a2..00000000000
--- a/solr/licenses/opentracing-noop-0.33.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-074b9950a587f53fbdb48c3f1f84f1ece8c10592
diff --git a/solr/licenses/opentracing-noop-LICENSE-ASL.txt b/solr/licenses/opentracing-noop-LICENSE-ASL.txt
deleted file mode 100644
index 261eeb9e9f8..00000000000
--- a/solr/licenses/opentracing-noop-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/solr/licenses/opentracing-noop-NOTICE.txt b/solr/licenses/opentracing-noop-NOTICE.txt
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/solr/licenses/opentracing-util-0.33.0.jar.sha1 b/solr/licenses/opentracing-util-0.33.0.jar.sha1
deleted file mode 100644
index b0c42dcc5bf..00000000000
--- a/solr/licenses/opentracing-util-0.33.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-132630f17e198a1748f23ce33597efdf4a807fb9
diff --git a/solr/licenses/opentracing-util-LICENSE-ASL.txt b/solr/licenses/opentracing-util-LICENSE-ASL.txt
deleted file mode 100644
index 261eeb9e9f8..00000000000
--- a/solr/licenses/opentracing-util-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/solr/licenses/opentracing-util-NOTICE.txt b/solr/licenses/opentracing-util-NOTICE.txt
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/solr/modules/opentelemetry/build.gradle b/solr/modules/opentelemetry/build.gradle
index 444d3c6ffb4..4426f67649e 100644
--- a/solr/modules/opentelemetry/build.gradle
+++ b/solr/modules/opentelemetry/build.gradle
@@ -21,17 +21,13 @@ description = 'Open Telemetry (OTEL) tracer'
dependencies {
implementation project(':solr:core')
+ implementation project(':solr:solrj')
implementation platform('io.opentelemetry:opentelemetry-bom')
-
- implementation 'io.opentracing:opentracing-api'
implementation 'org.slf4j:slf4j-api'
- implementation 'io.opentelemetry:opentelemetry-sdk'
- implementation 'io.opentelemetry:opentelemetry-sdk-trace'
+ implementation 'io.opentelemetry:opentelemetry-api'
implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure'
- implementation 'io.opentelemetry:opentelemetry-opentracing-shim'
- runtimeOnly 'io.opentelemetry:opentelemetry-semconv'
runtimeOnly 'io.opentelemetry:opentelemetry-exporter-otlp'
// End users must recompile with jaeger exporter and/or zipkin exporter if they need these
@@ -46,8 +42,8 @@ dependencies {
compileOnly 'org.apache.tomcat:annotations-api'
testImplementation project(':solr:test-framework')
- testImplementation project(':solr:solrj')
- testImplementation 'com.carrotsearch.randomizedtesting:randomizedtesting-runner'
testImplementation 'junit:junit'
- testImplementation 'io.opentracing:opentracing-util'
+ testImplementation 'io.opentelemetry:opentelemetry-sdk'
+ testImplementation 'io.opentelemetry:opentelemetry-sdk-trace'
+ testImplementation 'io.opentelemetry:opentelemetry-sdk-testing'
}
diff --git a/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/ClosableTracerShim.java b/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/ClosableTracerShim.java
deleted file mode 100644
index ee7fb962ce9..00000000000
--- a/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/ClosableTracerShim.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.solr.opentelemetry;
-
-import io.opentelemetry.sdk.trace.SdkTracerProvider;
-import io.opentracing.Scope;
-import io.opentracing.ScopeManager;
-import io.opentracing.Span;
-import io.opentracing.SpanContext;
-import io.opentracing.Tracer;
-import io.opentracing.propagation.Format;
-import java.lang.invoke.MethodHandles;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Delegate shim that forwards all calls to the actual {@link
- * io.opentelemetry.opentracingshim.OpenTracingShim}, and in addition calls {@link
- * SdkTracerProvider#close()} to really close the OTEL SDK tracer when the OT shim is closed.
- *
- * <p>TODO: This can be removed once we migrate Solr instrumentation from OpenTracing to
- * OpenTelemetry
- */
-public class ClosableTracerShim implements Tracer {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final Tracer shim;
- private final SdkTracerProvider sdkTracerProvider;
-
- public ClosableTracerShim(Tracer shim, SdkTracerProvider sdkTracerProvider) {
- this.shim = shim;
- this.sdkTracerProvider = sdkTracerProvider;
- }
-
- @Override
- public ScopeManager scopeManager() {
- return shim.scopeManager();
- }
-
- @Override
- public Span activeSpan() {
- return shim.activeSpan();
- }
-
- @Override
- public Scope activateSpan(Span span) {
- return shim.activateSpan(span);
- }
-
- @Override
- public SpanBuilder buildSpan(String operationName) {
- return shim.buildSpan(operationName);
- }
-
- @Override
- public <C> void inject(SpanContext spanContext, Format<C> format, C carrier) {
- shim.inject(spanContext, format, carrier);
- }
-
- @Override
- public <C> SpanContext extract(Format<C> format, C carrier) {
- return shim.extract(format, carrier);
- }
-
- @Override
- public void close() {
- shim.close();
- log.debug("Closing wrapped OTEL tracer instance.");
- sdkTracerProvider.forceFlush();
- sdkTracerProvider.close();
- }
-}
diff --git a/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/OtelTracerConfigurator.java b/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/OtelTracerConfigurator.java
index 6b876c7c1b6..25d819718dc 100644
--- a/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/OtelTracerConfigurator.java
+++ b/solr/modules/opentelemetry/src/java/org/apache/solr/opentelemetry/OtelTracerConfigurator.java
@@ -16,10 +16,9 @@
*/
package org.apache.solr.opentelemetry;
-import io.opentelemetry.opentracingshim.OpenTracingShim;
-import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
-import io.opentracing.Tracer;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.HashMap;
@@ -27,26 +26,45 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
+import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.TracerConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * OpenTracing TracerConfigurator implementation which exports spans to OpenTelemetry in OTLP
- * format. This impl re-uses the existing OpenTracing instrumentation through a shim, and takes care
- * of properly closing the backing Tracer when Solr shuts down.
+ * Tracing TracerConfigurator implementation which exports spans to OpenTelemetry in OTLP format.
*/
public class OtelTracerConfigurator extends TracerConfigurator {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- // Copy of environment. Can be overridden by tests
- Map<String, String> currentEnv = System.getenv();
+
+ private final Map<String, String> currentEnv;
+
+ public OtelTracerConfigurator() {
+ this(System.getenv());
+ }
+
+ OtelTracerConfigurator(Map<String, String> currentEnv) {
+ this.currentEnv = currentEnv;
+ }
@Override
public Tracer getTracer() {
+ // TODO remove reliance on global
+ return GlobalOpenTelemetry.getTracer("solr");
+ }
+
+ @Override
+ public void init(NamedList<?> args) {
+ prepareConfiguration();
+ AutoConfiguredOpenTelemetrySdk.initialize();
+ }
+
+ void prepareConfiguration() {
setDefaultIfNotConfigured("OTEL_SERVICE_NAME", "solr");
setDefaultIfNotConfigured("OTEL_TRACES_EXPORTER", "otlp");
setDefaultIfNotConfigured("OTEL_EXPORTER_OTLP_PROTOCOL", "grpc");
setDefaultIfNotConfigured("OTEL_TRACES_SAMPLER", "parentbased_always_on");
+ setDefaultIfNotConfigured("OTEL_PROPAGATORS", "tracecontext,baggage");
addOtelResourceAttributes(Map.of("host.name", System.getProperty("host")));
final String currentConfig = getCurrentOtelConfigAsString();
@@ -62,10 +80,6 @@ public class OtelTracerConfigurator extends TracerConfigurator {
}
System.setProperty("otel.metrics.exporter", "none");
System.setProperty("otel.logs.exporter", "none");
-
- OpenTelemetrySdk otelSdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
- Tracer shim = OpenTracingShim.createTracerShim(otelSdk);
- return new ClosableTracerShim(shim, otelSdk.getSdkTracerProvider());
}
/**
diff --git a/solr/modules/opentelemetry/src/test-files/solr/solr.xml b/solr/modules/opentelemetry/src/test-files/solr/solr.xml
index 6ad63be5e84..76926369f0d 100644
--- a/solr/modules/opentelemetry/src/test-files/solr/solr.xml
+++ b/solr/modules/opentelemetry/src/test-files/solr/solr.xml
@@ -34,7 +34,7 @@
<int name="connTimeout">${connTimeout:15000}</int>
</shardHandlerFactory>
- <tracerConfig name="tracerConfig" class="org.apache.solr.opentelemetry.OtelTracerConfigurator" />
+ <tracerConfig name="tracerConfig" class="org.apache.solr.opentelemetry.CustomTestOtelTracerConfigurator" />
<solrcloud>
<str name="host">127.0.0.1</str>
diff --git a/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/CustomTestOtelTracerConfigurator.java b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/CustomTestOtelTracerConfigurator.java
new file mode 100644
index 00000000000..bad6cce7d9f
--- /dev/null
+++ b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/CustomTestOtelTracerConfigurator.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.opentelemetry;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
+import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
+import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
+import java.lang.invoke.MethodHandles;
+import org.apache.solr.common.util.NamedList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CustomTestOtelTracerConfigurator extends OtelTracerConfigurator {
+
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ static {
+ if (System.getProperty("host") == null) {
+ System.setProperty("host", "localhost");
+ }
+ }
+
+ private static InMemorySpanExporter exporter;
+ private static volatile boolean isRegistered = false;
+ private static OpenTelemetrySdk otelSdk = null;
+
+ @Override
+ public synchronized Tracer getTracer() {
+ if (!isRegistered) {
+ throw new IllegalStateException(
+ "Tracer is not initialized. you need to call #prepareForTest for correct setup");
+ }
+ return super.getTracer();
+ }
+
+ @Override
+ public void init(NamedList<?> args) {
+ // prevent parent from init otel
+ }
+
+ public static synchronized void prepareForTest() {
+ CustomTestOtelTracerConfigurator.resetForTest();
+ isRegistered = true;
+ System.setProperty("otel.traces.exporter", "none");
+
+ // force early init
+ CustomTestOtelTracerConfigurator tracer = new CustomTestOtelTracerConfigurator();
+ tracer.prepareConfiguration();
+
+ bootOtel();
+ }
+
+ private static void bootOtel() {
+ try {
+ exporter = InMemorySpanExporter.create();
+ otelSdk =
+ AutoConfiguredOpenTelemetrySdk.builder()
+ .setResultAsGlobal()
+ .addTracerProviderCustomizer(
+ (builder, props) ->
+ builder.addSpanProcessor(SimpleSpanProcessor.create(exporter)))
+ .build()
+ .getOpenTelemetrySdk();
+ } catch (RuntimeException e) {
+ log.error("Error on OTEL init ", e);
+ }
+ }
+
+ public static InMemorySpanExporter getInMemorySpanExporter() {
+ return exporter;
+ }
+
+ public static synchronized void resetForTest() {
+ if (isRegistered) {
+ isRegistered = false;
+ if (otelSdk != null) {
+ otelSdk.close();
+ }
+ if (exporter != null) {
+ exporter.close();
+ exporter = null;
+ }
+ System.clearProperty("otel.traces.exporter");
+ GlobalOpenTelemetry.resetForTest();
+ }
+ }
+}
diff --git a/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/OtelTracerConfiguratorTest.java b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/OtelTracerConfiguratorTest.java
index 5aef12103da..b4825c4e7fd 100644
--- a/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/OtelTracerConfiguratorTest.java
+++ b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/OtelTracerConfiguratorTest.java
@@ -16,18 +16,13 @@
*/
package org.apache.solr.opentelemetry;
-import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering;
-import io.opentracing.util.GlobalTracer;
import java.util.List;
import java.util.Map;
import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.cloud.MiniSolrCloudCluster;
-import org.apache.solr.common.util.ExecutorUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-@ThreadLeakLingering(linger = 10000)
public class OtelTracerConfiguratorTest extends SolrTestCaseJ4 {
private OtelTracerConfigurator instance;
@@ -35,8 +30,7 @@ public class OtelTracerConfiguratorTest extends SolrTestCaseJ4 {
@Before
public void setUp() throws Exception {
super.setUp();
- instance = new OtelTracerConfigurator();
- instance.currentEnv =
+ Map<String, String> currentEnv =
Map.of(
"OTELNOTHERE", "foo",
"OTEL_K1", "env-k1",
@@ -44,10 +38,8 @@ public class OtelTracerConfiguratorTest extends SolrTestCaseJ4 {
System.setProperty("otelnothere", "bar");
System.setProperty("otel.k1", "prop-k1");
System.setProperty("otel.k3", "prop-k3");
-
- // to be safe because this test tests tracing.
- resetGlobalTracer();
- ExecutorUtil.resetThreadLocalProviders();
+ System.setProperty("host", "my.solr.host");
+ instance = new OtelTracerConfigurator(currentEnv);
}
@Override
@@ -57,7 +49,8 @@ public class OtelTracerConfiguratorTest extends SolrTestCaseJ4 {
System.clearProperty("otelnothere");
System.clearProperty("otel.k1");
System.clearProperty("otel.k3");
- System.clearProperty("otel.bsp.export.timeout");
+ System.clearProperty("host");
+ System.clearProperty("otel.resource.attributes");
}
@Test
@@ -93,28 +86,11 @@ public class OtelTracerConfiguratorTest extends SolrTestCaseJ4 {
}
@Test
- public void testInjected() throws Exception {
+ public void testResourceAttributes() throws Exception {
System.setProperty("otel.resource.attributes", "foo=bar,ILLEGAL-LACKS-VALUE,");
- System.setProperty("host", "my.solr.host");
- // Make sure the batch exporter times out before our thread lingering time of 10s
- instance.setDefaultIfNotConfigured("OTEL_BSP_SCHEDULE_DELAY", "1000");
- instance.setDefaultIfNotConfigured("OTEL_BSP_EXPORT_TIMEOUT", "2000");
- MiniSolrCloudCluster cluster =
- new MiniSolrCloudCluster.Builder(2, createTempDir())
- .addConfig("config", TEST_PATH().resolve("collection1").resolve("conf"))
- .withSolrXml(getFile("solr/solr.xml").toPath())
- .build();
- try {
- assertTrue(
- "Tracer shim not registered with GlobalTracer",
- GlobalTracer.get().toString().contains("ClosableTracerShim"));
- assertEquals(
- List.of("host.name=my.solr.host", "foo=bar"),
- List.of(System.getProperty("otel.resource.attributes").split(",")));
- } finally {
- cluster.shutdown();
- System.clearProperty("otel.resource.attributes");
- System.clearProperty("host");
- }
+ instance.prepareConfiguration();
+ assertEquals(
+ List.of("host.name=my.solr.host", "foo=bar"),
+ List.of(System.getProperty("otel.resource.attributes").split(",")));
}
}
diff --git a/solr/core/src/test/org/apache/solr/util/tracing/TestDistributedTracing.java b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/TestDistributedTracing.java
similarity index 56%
rename from solr/core/src/test/org/apache/solr/util/tracing/TestDistributedTracing.java
rename to solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/TestDistributedTracing.java
index b28f15e18bd..dea832e87f6 100644
--- a/solr/core/src/test/org/apache/solr/util/tracing/TestDistributedTracing.java
+++ b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/TestDistributedTracing.java
@@ -15,12 +15,15 @@
* limitations under the License.
*/
-package org.apache.solr.util.tracing;
+package org.apache.solr.opentelemetry;
-import io.opentracing.mock.MockSpan;
-import io.opentracing.mock.MockTracer;
-import io.opentracing.util.GlobalTracer;
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.SpanContext;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
+import io.opentelemetry.sdk.trace.data.SpanData;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -34,56 +37,60 @@ import org.apache.solr.client.solrj.request.V2Request;
import org.apache.solr.client.solrj.response.V2Response;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.util.LogLevel;
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
+import org.apache.solr.util.tracing.TraceUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
-@LogLevel("org.apache.solr.core.TracerConfigurator=trace")
public class TestDistributedTracing extends SolrCloudTestCase {
- private static final String COLLECTION = "collection1";
- static MockTracer tracer;
+ private static final String COLLECTION = "collection1";
@BeforeClass
- public static void beforeTest() throws Exception {
- tracer = new MockTracer();
- assertTrue(GlobalTracer.registerIfAbsent(tracer));
+ public static void setupCluster() throws Exception {
+ // force early init
+ CustomTestOtelTracerConfigurator.prepareForTest();
configureCluster(4)
- .addConfig(
- "config", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
+ .addConfig("config", TEST_PATH().resolve("collection1").resolve("conf"))
+ .withSolrXml(TEST_PATH().resolve("solr.xml"))
.configure();
+
+ assertNotEquals(
+ "Expecting active otel, not noop impl",
+ TracerProvider.noop(),
+ GlobalOpenTelemetry.get().getTracerProvider());
+
CollectionAdminRequest.createCollection(COLLECTION, "config", 2, 2)
- .setPerReplicaState(SolrCloudTestCase.USE_PER_REPLICA_STATE)
.process(cluster.getSolrClient());
cluster.waitForActiveCollection(COLLECTION, 2, 4);
}
@AfterClass
- public static void afterTest() {
- tracer = null;
+ public static void afterClass() {
+ CustomTestOtelTracerConfigurator.resetForTest();
}
@Test
public void test() throws IOException, SolrServerException {
// TODO it would be clearer if we could compare the complete Span tree between reality
- // and what we assert it looks like in a structured visual way.
+ // and what we assert it looks like in a structured visual way.
+ getAndClearSpans(); // reset
CloudSolrClient cloudClient = cluster.getSolrClient();
- List<MockSpan> finishedSpans;
// Indexing
cloudClient.add(COLLECTION, sdoc("id", "1"));
- finishedSpans = getAndClearSpans();
- finishedSpans.removeIf(x -> !x.tags().get("http.url").toString().endsWith("/update"));
+ var finishedSpans = getAndClearSpans();
+ finishedSpans.removeIf(
+ span ->
+ span.getAttributes().get(TraceUtils.TAG_HTTP_URL) == null
+ || !span.getAttributes().get(TraceUtils.TAG_HTTP_URL).endsWith("/update"));
assertEquals(2, finishedSpans.size());
assertOneSpanIsChildOfAnother(finishedSpans);
// core because cloudClient routes to core
- assertEquals("post:/{core}/update", finishedSpans.get(0).operationName());
- assertDbInstanceCore(finishedSpans.get(0));
+ assertEquals("post:/{core}/update", finishedSpans.get(0).getName());
+ assertCoreName(finishedSpans.get(0));
cloudClient.add(COLLECTION, sdoc("id", "2"));
cloudClient.add(COLLECTION, sdoc("id", "3"));
@@ -94,54 +101,58 @@ public class TestDistributedTracing extends SolrCloudTestCase {
// Searching
cloudClient.query(COLLECTION, new SolrQuery("*:*"));
finishedSpans = getAndClearSpans();
- finishedSpans.removeIf(x -> !x.tags().get("http.url").toString().endsWith("/select"));
+ finishedSpans.removeIf(
+ span ->
+ span.getAttributes().get(TraceUtils.TAG_HTTP_URL) == null
+ || !span.getAttributes().get(TraceUtils.TAG_HTTP_URL).endsWith("/select"));
// one from client to server, 2 for execute query, 2 for fetching documents
assertEquals(5, finishedSpans.size());
- assertEquals(1, finishedSpans.stream().filter(s -> s.parentId() == 0).count());
- long parentId =
+ assertEquals(1, finishedSpans.stream().filter(TestDistributedTracing::isRootSpan).count());
+ var parentTraceId =
finishedSpans.stream()
- .filter(s -> s.parentId() == 0)
+ .filter(TestDistributedTracing::isRootSpan)
.collect(Collectors.toList())
.get(0)
- .context()
- .spanId();
- for (MockSpan span : finishedSpans) {
- if (span.parentId() != 0 && parentId != span.parentId()) {
- fail("All spans must belong to single span, but:" + finishedSpans);
+ .getSpanContext()
+ .getTraceId();
+ for (var span : finishedSpans) {
+ if (isRootSpan(span)) {
+ continue;
}
+ assertEquals(span.getParentSpanContext().getTraceId(), parentTraceId);
+ assertEquals(span.getTraceId(), parentTraceId);
}
- assertEquals("get:/{core}/select", finishedSpans.get(0).operationName());
- assertDbInstanceCore(finishedSpans.get(0));
+ assertEquals("get:/{core}/select", finishedSpans.get(0).getName());
+ assertCoreName(finishedSpans.get(0));
}
@Test
public void testAdminApi() throws Exception {
+ getAndClearSpans(); // reset
CloudSolrClient cloudClient = cluster.getSolrClient();
- List<MockSpan> finishedSpans;
- // Admin API call
cloudClient.request(new GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/metrics"));
- finishedSpans = getAndClearSpans();
- assertEquals("get:/admin/metrics", finishedSpans.get(0).operationName());
+ var finishedSpans = getAndClearSpans();
+ assertEquals("get:/admin/metrics", finishedSpans.get(0).getName());
CollectionAdminRequest.listCollections(cloudClient);
finishedSpans = getAndClearSpans();
- assertEquals("list:/admin/collections", finishedSpans.get(0).operationName());
+ assertEquals("list:/admin/collections", finishedSpans.get(0).getName());
}
@Test
public void testV2Api() throws Exception {
+ getAndClearSpans(); // reset
CloudSolrClient cloudClient = cluster.getSolrClient();
- List<MockSpan> finishedSpans;
new V2Request.Builder("/collections/" + COLLECTION + "/reload")
.withMethod(SolrRequest.METHOD.POST)
.withPayload("{}")
.build()
.process(cloudClient);
- finishedSpans = getAndClearSpans();
- assertEquals("post:/collections/{collection}/reload", finishedSpans.get(0).operationName());
- assertDbInstanceColl(finishedSpans.get(0));
+ var finishedSpans = getAndClearSpans();
+ assertEquals("post:/collections/{collection}/reload", finishedSpans.get(0).getName());
+ assertCollectionName(finishedSpans.get(0));
new V2Request.Builder("/c/" + COLLECTION + "/update/json")
.withMethod(SolrRequest.METHOD.POST)
@@ -150,8 +161,8 @@ public class TestDistributedTracing extends SolrCloudTestCase {
.build()
.process(cloudClient);
finishedSpans = getAndClearSpans();
- assertEquals("post:/c/{collection}/update/json", finishedSpans.get(0).operationName());
- assertDbInstanceColl(finishedSpans.get(0));
+ assertEquals("post:/c/{collection}/update/json", finishedSpans.get(0).getName());
+ assertCollectionName(finishedSpans.get(0));
final V2Response v2Response =
new V2Request.Builder("/c/" + COLLECTION + "/select")
@@ -160,36 +171,40 @@ public class TestDistributedTracing extends SolrCloudTestCase {
.build()
.process(cloudClient);
finishedSpans = getAndClearSpans();
- assertEquals("get:/c/{collection}/select", finishedSpans.get(0).operationName());
- assertDbInstanceColl(finishedSpans.get(0));
+ assertEquals("get:/c/{collection}/select", finishedSpans.get(0).getName());
+ assertCollectionName(finishedSpans.get(0));
assertEquals(1, ((SolrDocumentList) v2Response.getResponse().get("response")).getNumFound());
}
- private void assertDbInstanceColl(MockSpan mockSpan) {
- MatcherAssert.assertThat(mockSpan.tags().get("db.instance"), Matchers.equalTo("collection1"));
+ private static boolean isRootSpan(SpanData span) {
+ return span.getParentSpanContext() == SpanContext.getInvalid();
}
- private void assertDbInstanceCore(MockSpan mockSpan) {
- MatcherAssert.assertThat(
- (String) mockSpan.tags().get("db.instance"), Matchers.startsWith("collection1_"));
+ private static void assertCollectionName(SpanData span) {
+ assertEquals(COLLECTION, span.getAttributes().get(TraceUtils.TAG_DB));
}
- private void assertOneSpanIsChildOfAnother(List<MockSpan> finishedSpans) {
- MockSpan child = finishedSpans.get(0);
- MockSpan parent = finishedSpans.get(1);
- if (child.parentId() == 0) {
- MockSpan temp = parent;
+ private static void assertCoreName(SpanData span) {
+ assertTrue(span.getAttributes().get(TraceUtils.TAG_DB).startsWith(COLLECTION + "_"));
+ }
+
+ private void assertOneSpanIsChildOfAnother(List<SpanData> finishedSpans) {
+ SpanData child = finishedSpans.get(0);
+ SpanData parent = finishedSpans.get(1);
+ if (isRootSpan(child)) {
+ var temp = parent;
parent = child;
child = temp;
}
-
- assertEquals(child.parentId(), parent.context().spanId());
+ assertEquals(child.getParentSpanContext().getTraceId(), parent.getTraceId());
+ assertEquals(child.getTraceId(), parent.getTraceId());
}
- private List<MockSpan> getAndClearSpans() {
- List<MockSpan> result = tracer.finishedSpans(); // returns a mutable copy
+ private List<SpanData> getAndClearSpans() {
+ InMemorySpanExporter exporter = CustomTestOtelTracerConfigurator.getInMemorySpanExporter();
+ List<SpanData> result = new ArrayList<>(exporter.getFinishedSpanItems());
Collections.reverse(result); // nicer to see spans chronologically
- tracer.reset();
+ exporter.reset();
return result;
}
}
diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index 33e386b6b46..fed3ed14110 100644
--- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -34,6 +34,8 @@ Starting in 10, the Maven POM for SolrJ does not refer to SolrJ modules like Zoo
* The `jaegertracer-configurator` module, which was deprecated in 9.2, is removed. Users should migrate to the `opentelemetry` module.
+* `OpenTracing` libraries were removed and replaced with `OpenTelemetry` libraries. Any Java agents providing `OpenTracing` tracers will no longer work. Telemetry tags `http.status_code` and `http.method` have been deprecated, newer version of the tags have been added to the span data: `http.response.status_code`, `http.request.method`.
+
* The `analytics` module, which was deprecated in 9.2, is removed.
* The sysProp `-Dsolr.redaction.system.pattern`, which allows users to provide a pattern to match sysProps that should be redacted for sensitive information,
diff --git a/solr/test-framework/build.gradle b/solr/test-framework/build.gradle
index c6589155072..6c772aac512 100644
--- a/solr/test-framework/build.gradle
+++ b/solr/test-framework/build.gradle
@@ -52,8 +52,6 @@ dependencies {
implementation 'org.slf4j:slf4j-api'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.apache.logging.log4j:log4j-core'
- implementation 'io.opentracing:opentracing-noop'
- implementation 'io.opentracing:opentracing-util'
implementation 'io.dropwizard.metrics:metrics-core'
implementation 'io.dropwizard.metrics:metrics-jetty10'
implementation 'commons-cli:commons-cli'
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index ba96e729562..fc4a6ac27fb 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -20,15 +20,12 @@ import static java.util.Objects.requireNonNull;
import static org.apache.solr.cloud.SolrZkServer.ZK_WHITELIST_PROPERTY;
import static org.apache.solr.common.cloud.ZkStateReader.HTTPS;
import static org.apache.solr.common.cloud.ZkStateReader.URL_SCHEME;
-import static org.apache.solr.update.processor.DistributedUpdateProcessor.DistribPhase;
import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM;
import static org.hamcrest.core.StringContains.containsString;
import com.carrotsearch.randomizedtesting.RandomizedContext;
import com.carrotsearch.randomizedtesting.RandomizedTest;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
-import io.opentracing.noop.NoopTracerFactory;
-import io.opentracing.util.GlobalTracer;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
@@ -43,7 +40,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
@@ -52,8 +48,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.ArrayList;
@@ -138,6 +132,7 @@ import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.security.AllowListUrlChecker;
import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.update.processor.DistributedUpdateProcessor;
+import org.apache.solr.update.processor.DistributedUpdateProcessor.DistribPhase;
import org.apache.solr.update.processor.DistributedZkUpdateProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.util.BaseTestHarness;
@@ -313,38 +308,9 @@ public abstract class SolrTestCaseJ4 extends SolrTestCase {
System.setProperty(URL_SCHEME, HTTPS);
}
- resetGlobalTracer();
ExecutorUtil.resetThreadLocalProviders();
}
- /**
- * GlobalTracer is initialized by org.apache.solr.core.TracerConfigurator by
- * org.apache.solr.core.CoreContainer. Tests may need to reset it in the beginning of a test if it
- * might have differing configuration from other tests in the same suite. It's also important to
- * call {@link ExecutorUtil#resetThreadLocalProviders()}.
- */
- @SuppressForbidden(reason = "Hack to reset internal state of GlobalTracer")
- public static void resetGlobalTracer() {
- AccessController.doPrivileged(
- (PrivilegedAction<Void>)
- () -> {
- try {
- final Class<GlobalTracer> globalTracerClass = GlobalTracer.class;
- final Field isRegistered = globalTracerClass.getDeclaredField("isRegistered");
- isRegistered.setAccessible(true);
- isRegistered.setBoolean(null, false);
- final Field tracer = globalTracerClass.getDeclaredField("tracer");
- tracer.setAccessible(true);
- tracer.set(null, NoopTracerFactory.create());
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- return null;
- });
-
- assert GlobalTracer.isRegistered() == false;
- }
-
@AfterClass
public static void teardownTestCases() throws Exception {
TestInjection.notifyPauseForeverDone();
diff --git a/versions.lock b/versions.lock
index c78c403b7d4..f79f9dba576 100644
--- a/versions.lock
+++ b/versions.lock
@@ -124,7 +124,7 @@ io.netty:netty-transport-native-unix-common:4.1.96.Final (4 constraints: 5e3d199
io.opencensus:opencensus-api:0.31.1 (5 constraints: 924d4692)
io.opencensus:opencensus-contrib-http-util:0.31.1 (3 constraints: 7232a9fc)
io.opencensus:opencensus-proto:0.2.0 (1 constraints: e60fd595)
-io.opentelemetry:opentelemetry-api:1.29.0 (11 constraints: ceca6768)
+io.opentelemetry:opentelemetry-api:1.29.0 (11 constraints: c3c8daff)
io.opentelemetry:opentelemetry-api-events:1.29.0-alpha (2 constraints: 332f2380)
io.opentelemetry:opentelemetry-bom:1.29.0 (1 constraints: 3e05483b)
io.opentelemetry:opentelemetry-context:1.29.0 (2 constraints: 2d1f62b5)
@@ -133,18 +133,14 @@ io.opentelemetry:opentelemetry-exporter-otlp:1.29.0 (1 constraints: 990ff983)
io.opentelemetry:opentelemetry-exporter-otlp-common:1.29.0 (2 constraints: 5823eb1c)
io.opentelemetry:opentelemetry-exporter-sender-okhttp:1.29.0 (2 constraints: 5823eb1c)
io.opentelemetry:opentelemetry-extension-incubator:1.29.0-alpha (1 constraints: f414ee96)
-io.opentelemetry:opentelemetry-opentracing-shim:1.29.0 (1 constraints: 990ff983)
-io.opentelemetry:opentelemetry-sdk:1.29.0 (3 constraints: ae4376e7)
+io.opentelemetry:opentelemetry-sdk:1.29.0 (4 constraints: 755634c7)
io.opentelemetry:opentelemetry-sdk-common:1.29.0 (6 constraints: 936c396e)
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.29.0 (1 constraints: 990ff983)
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.29.0 (3 constraints: a63c5427)
io.opentelemetry:opentelemetry-sdk-logs:1.29.0 (3 constraints: f43275b4)
io.opentelemetry:opentelemetry-sdk-metrics:1.29.0 (3 constraints: f43275b4)
io.opentelemetry:opentelemetry-sdk-trace:1.29.0 (3 constraints: f43275b4)
-io.opentelemetry:opentelemetry-semconv:1.29.0-alpha (4 constraints: 175b2583)
-io.opentracing:opentracing-api:0.33.0 (5 constraints: 7244331d)
-io.opentracing:opentracing-noop:0.33.0 (4 constraints: 48361e21)
-io.opentracing:opentracing-util:0.33.0 (2 constraints: 5013be5a)
+io.opentelemetry:opentelemetry-semconv:1.29.0-alpha (4 constraints: 0c5920ad)
io.perfmark:perfmark-api:0.26.0 (3 constraints: 21212b16)
io.prometheus:simpleclient:0.16.0 (3 constraints: 9d257513)
io.prometheus:simpleclient_common:0.16.0 (1 constraints: 1a1139c0)
@@ -403,7 +399,7 @@ com.squareup.okhttp3:mockwebserver:4.9.3 (1 constraints: c60ebf62)
io.github.microutils:kotlin-logging:2.1.21 (1 constraints: ec0e8871)
io.github.microutils:kotlin-logging-jvm:2.1.21 (1 constraints: af0f358c)
io.micrometer:micrometer-core:1.9.11 (1 constraints: fd162819)
-io.opentracing:opentracing-mock:0.33.0 (1 constraints: 3805343b)
+io.opentelemetry:opentelemetry-sdk-testing:1.29.0 (1 constraints: 990ff983)
jakarta.servlet:jakarta.servlet-api:4.0.4 (4 constraints: 586e1f6a)
jakarta.websocket:jakarta.websocket-api:1.1.2 (1 constraints: 92155ab9)
javax.inject:javax.inject:1 (1 constraints: 7a0df617)
diff --git a/versions.props b/versions.props
index 45ffbbad5d4..41be40abeeb 100644
--- a/versions.props
+++ b/versions.props
@@ -24,7 +24,6 @@ io.dropwizard.metrics:*=4.2.19
io.grpc:grpc-*=1.56.0
io.netty:*=4.1.96.Final
io.opentelemetry:opentelemetry-bom=1.29.0
-io.opentracing:*=0.33.0
io.prometheus:*=0.16.0
io.swagger.core.v3:*=2.2.12
jakarta.ws.rs:jakarta.ws.rs-api=2.1.6