org.apache.solr.core.TracerConfigurator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of solr-core Show documentation
Show all versions of solr-core Show documentation
Apache Solr (module: core)
/*
* 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.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.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.common.util.ExecutorUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import org.apache.solr.util.tracing.SimplePropagator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Produces an OpenTracing {@link Tracer} from configuration. */
public abstract class TracerConfigurator implements NamedListInitializedPlugin {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static final boolean TRACE_ID_GEN_ENABLED =
Boolean.parseBoolean(EnvUtils.getProperty("solr.alwaysOnTraceId", "true"));
private static final String DEFAULT_CLASS_NAME =
EnvUtils.getProperty(
"solr.otelDefaultConfigurator", "org.apache.solr.opentelemetry.OtelTracerConfigurator");
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();
});
} else if (shouldAutoConfigOTEL()) {
GlobalTracer.registerIfAbsent(() -> autoConfigOTEL(loader));
} else if (TRACE_ID_GEN_ENABLED) {
SimplePropagator.load();
}
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());
}
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).
*
* 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