This is an automated email from the ASF dual-hosted git repository.

gus 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 a867e72a9e0 SOLR-18047 Move tracing initialization to TracingFilter 
(#4108)
a867e72a9e0 is described below

commit a867e72a9e01bb21c1731459dc0b2a8b6fdfe77f
Author: Gus Heck <[email protected]>
AuthorDate: Mon Feb 9 02:13:34 2026 -0500

    SOLR-18047 Move tracing initialization to TracingFilter (#4108)
---
 changelog/unreleased/SOLR-18047.yml                |  8 +++
 .../apache/solr/servlet/ExceptionWhileTracing.java | 28 ----------
 .../org/apache/solr/servlet/RateLimitFilter.java   | 13 +----
 .../java/org/apache/solr/servlet/ServletUtils.java | 50 -----------------
 .../org/apache/solr/servlet/TracingFilter.java     | 62 ++++++++++++++++++++++
 .../org/apache/solr/embedded/JettySolrRunner.java  |  7 +++
 solr/webapp/web/WEB-INF/web.xml                    | 10 ++++
 7 files changed, 88 insertions(+), 90 deletions(-)

diff --git a/changelog/unreleased/SOLR-18047.yml 
b/changelog/unreleased/SOLR-18047.yml
new file mode 100644
index 00000000000..c8474de0496
--- /dev/null
+++ b/changelog/unreleased/SOLR-18047.yml
@@ -0,0 +1,8 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Initialization of tracing spans has moved to TracingFilter
+type: other # added, changed, fixed, deprecated, removed, dependency_update, 
security, other
+authors:
+  - name: Gus Heck
+links:
+  - name: SOLR-18047
+    url: https://issues.apache.org/jira/browse/SOLR-18047
diff --git 
a/solr/core/src/java/org/apache/solr/servlet/ExceptionWhileTracing.java 
b/solr/core/src/java/org/apache/solr/servlet/ExceptionWhileTracing.java
deleted file mode 100644
index c01d3d0c3f8..00000000000
--- a/solr/core/src/java/org/apache/solr/servlet/ExceptionWhileTracing.java
+++ /dev/null
@@ -1,28 +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.servlet;
-
-/*
- * This is not pretty, hope to remove it when tracing becomes a filter.
- */
-public class ExceptionWhileTracing extends RuntimeException {
-  public Exception e;
-
-  public ExceptionWhileTracing(Exception e) {
-    this.e = e;
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/servlet/RateLimitFilter.java 
b/solr/core/src/java/org/apache/solr/servlet/RateLimitFilter.java
index 6f0d301e086..2f8990fdea1 100644
--- a/solr/core/src/java/org/apache/solr/servlet/RateLimitFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/RateLimitFilter.java
@@ -47,18 +47,7 @@ public class RateLimitFilter extends 
CoreContainerAwareHttpFilter {
             SolrException.ErrorCode.TOO_MANY_REQUESTS.code, 
RateLimitManager.ERROR_MESSAGE);
         return;
       }
-      // todo: this shouldn't be required, tracing and rate limiting should be 
independently
-      //  composable
-      ServletUtils.traceHttpRequestExecution2(
-          req,
-          res,
-          () -> {
-            try {
-              chain.doFilter(req, res);
-            } catch (Exception e) {
-              throw new ExceptionWhileTracing(e);
-            }
-          });
+      chain.doFilter(req, res);
     } catch (InterruptedException e1) {
       Thread.currentThread().interrupt();
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, 
e1.getMessage());
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 97af38d8b27..d188e627ef7 100644
--- a/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java
+++ b/solr/core/src/java/org/apache/solr/servlet/ServletUtils.java
@@ -17,10 +17,7 @@
 
 package org.apache.solr.servlet;
 
-import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.context.Context;
 import jakarta.servlet.ReadListener;
-import jakarta.servlet.ServletException;
 import jakarta.servlet.ServletInputStream;
 import jakarta.servlet.ServletOutputStream;
 import jakarta.servlet.WriteListener;
@@ -33,8 +30,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.invoke.MethodHandles;
 import org.apache.solr.common.util.Utils;
-import org.apache.solr.logging.MDCLoggingContext;
-import org.apache.solr.util.tracing.TraceUtils;
 import org.eclipse.jetty.http.HttpHeader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -124,51 +119,6 @@ public abstract class ServletUtils {
     };
   }
 
-  /**
-   * Sets up tracing for an HTTP request. Perhaps should be converted to a 
servlet filter at some
-   * point.
-   *
-   * @param request The request to limit
-   * @param response The associated response
-   * @param tracedExecution the executed code
-   */
-  static void traceHttpRequestExecution2(
-      HttpServletRequest request, HttpServletResponse response, Runnable 
tracedExecution)
-      throws ServletException, IOException {
-    Context context = TraceUtils.extractContext(request);
-    Span span = TraceUtils.startHttpRequestSpan(request, context);
-
-    final Thread currentThread = Thread.currentThread();
-    final String oldThreadName = currentThread.getName();
-    try (var scope = context.with(span).makeCurrent()) {
-      assert scope != null; // prevent javac warning about scope being unused
-      TraceUtils.setSpan(request, span);
-      TraceUtils.ifValidTraceId(
-          span, s -> 
MDCLoggingContext.setTracerId(s.getSpanContext().getTraceId()));
-      String traceId = MDCLoggingContext.getTraceId();
-      if (traceId != null) {
-        currentThread.setName(oldThreadName + "-" + traceId);
-      }
-      tracedExecution.run();
-    } catch (ExceptionWhileTracing e) {
-      if (e.e instanceof ServletException) {
-        throw (ServletException) e.e;
-      }
-      if (e.e instanceof IOException) {
-        throw (IOException) e.e;
-      }
-      if (e.e instanceof RuntimeException) {
-        throw (RuntimeException) e.e;
-      } else {
-        throw new RuntimeException(e.e);
-      }
-    } finally {
-      currentThread.setName(oldThreadName);
-      TraceUtils.setHttpStatus(span, response.getStatus());
-      span.end();
-    }
-  }
-
   // we make sure we read the full client request so that the client does
   // not hit a connection reset and we can reuse the
   // connection - see SOLR-8453 and SOLR-8683
diff --git a/solr/core/src/java/org/apache/solr/servlet/TracingFilter.java 
b/solr/core/src/java/org/apache/solr/servlet/TracingFilter.java
new file mode 100644
index 00000000000..3371d26d98c
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/servlet/TracingFilter.java
@@ -0,0 +1,62 @@
+/*
+ * 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.servlet;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Context;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpFilter;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import org.apache.solr.logging.MDCLoggingContext;
+import org.apache.solr.util.tracing.TraceUtils;
+
+/**
+ * Filter for distributed tracing. This filter creates a span for this 
request. While this filter
+ * could be replaced, the replacement must supply an instance of 
io.opentelemetry.api.trace.Span for
+ * use in the rest of solr.
+ */
+public class TracingFilter extends HttpFilter {
+
+  @Override
+  protected void doFilter(HttpServletRequest req, HttpServletResponse res, 
FilterChain chain)
+      throws IOException, ServletException {
+    Context context = TraceUtils.extractContext(req);
+    Span span = TraceUtils.startHttpRequestSpan(req, context);
+
+    final Thread currentThread = Thread.currentThread();
+    final String oldThreadName = currentThread.getName();
+    try (var scope = context.with(span).makeCurrent()) {
+      assert scope != null; // prevent javac warning about scope being unused
+      TraceUtils.setSpan(req, span);
+      TraceUtils.ifValidTraceId(
+          span, s -> 
MDCLoggingContext.setTracerId(s.getSpanContext().getTraceId()));
+      String traceId = MDCLoggingContext.getTraceId();
+      if (traceId != null) {
+        currentThread.setName(oldThreadName + "-" + traceId);
+      }
+      chain.doFilter(req, res);
+    } finally {
+      currentThread.setName(oldThreadName);
+      TraceUtils.setHttpStatus(span, res.getStatus());
+      span.end();
+    }
+  }
+}
diff --git 
a/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java 
b/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
index 2530ed7acd4..e4224e44e6c 100644
--- a/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
+++ b/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
@@ -65,6 +65,7 @@ import org.apache.solr.servlet.PathExclusionFilter;
 import org.apache.solr.servlet.RateLimitFilter;
 import org.apache.solr.servlet.RequiredSolrRequestFilter;
 import org.apache.solr.servlet.SolrDispatchFilter;
+import org.apache.solr.servlet.TracingFilter;
 import org.apache.solr.util.SocketProxy;
 import org.apache.solr.util.TimeOut;
 import org.apache.solr.util.configuration.SSLConfigurationsFactory;
@@ -117,6 +118,7 @@ public class JettySolrRunner {
   volatile FilterHolder requiredFilter;
   volatile FilterHolder rateLimitFilter;
   volatile FilterHolder dispatchFilter;
+  private FilterHolder tracingFilter;
 
   private int jettyPort = -1;
 
@@ -421,6 +423,10 @@ public class JettySolrRunner {
       rateLimitFilter = 
root.getServletHandler().newFilterHolder(Source.EMBEDDED);
       rateLimitFilter.setHeldClass(RateLimitFilter.class);
 
+      // Ratelimit Requests
+      tracingFilter = 
root.getServletHandler().newFilterHolder(Source.EMBEDDED);
+      tracingFilter.setHeldClass(TracingFilter.class);
+
       // This is our main workhorse
       dispatchFilter = 
root.getServletHandler().newFilterHolder(Source.EMBEDDED);
       dispatchFilter.setHeldClass(SolrDispatchFilter.class);
@@ -429,6 +435,7 @@ public class JettySolrRunner {
       root.addFilter(pathExcludeFilter, "/*", 
EnumSet.of(DispatcherType.REQUEST));
       root.addFilter(requiredFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
       root.addFilter(rateLimitFilter, "/*", 
EnumSet.of(DispatcherType.REQUEST));
+      root.addFilter(tracingFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
       root.addFilter(dispatchFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
 
       // Default servlet as a fall-through
diff --git a/solr/webapp/web/WEB-INF/web.xml b/solr/webapp/web/WEB-INF/web.xml
index e383133ea6d..6732a6cb58a 100644
--- a/solr/webapp/web/WEB-INF/web.xml
+++ b/solr/webapp/web/WEB-INF/web.xml
@@ -64,6 +64,16 @@
     <url-pattern>/*</url-pattern>
   </filter-mapping>
 
+  <filter>
+    <filter-name>TracingFilter</filter-name>
+    <filter-class>org.apache.solr.servlet.TracingFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>TracingFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
   <filter>
     <filter-name>SolrRequestFilter</filter-name>
     <filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class>

Reply via email to