Skip to content

Commit b9f6c83

Browse files
authored
SOLR-18047 Move tracing initialization to TracingFilter (backport #4108) (#4197)
1 parent d977d7e commit b9f6c83

7 files changed

Lines changed: 88 additions & 90 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
2+
title: Initialization of tracing spans has moved to TracingFilter
3+
type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other
4+
authors:
5+
- name: Gus Heck
6+
links:
7+
- name: SOLR-18047
8+
url: https://issues.apache.org/jira/browse/SOLR-18047

solr/core/src/java/org/apache/solr/servlet/ExceptionWhileTracing.java

Lines changed: 0 additions & 28 deletions
This file was deleted.

solr/core/src/java/org/apache/solr/servlet/RateLimitFilter.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,7 @@ protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterC
4747
SolrException.ErrorCode.TOO_MANY_REQUESTS.code, RateLimitManager.ERROR_MESSAGE);
4848
return;
4949
}
50-
// todo: this shouldn't be required, tracing and rate limiting should be independently
51-
// composable
52-
ServletUtils.traceHttpRequestExecution2(
53-
req,
54-
res,
55-
() -> {
56-
try {
57-
chain.doFilter(req, res);
58-
} catch (Exception e) {
59-
throw new ExceptionWhileTracing(e);
60-
}
61-
});
50+
chain.doFilter(req, res);
6251
} catch (InterruptedException e1) {
6352
Thread.currentThread().interrupt();
6453
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e1.getMessage());

solr/core/src/java/org/apache/solr/servlet/ServletUtils.java

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717

1818
package org.apache.solr.servlet;
1919

20-
import io.opentelemetry.api.trace.Span;
21-
import io.opentelemetry.context.Context;
2220
import jakarta.servlet.ReadListener;
23-
import jakarta.servlet.ServletException;
2421
import jakarta.servlet.ServletInputStream;
2522
import jakarta.servlet.ServletOutputStream;
2623
import jakarta.servlet.WriteListener;
@@ -33,8 +30,6 @@
3330
import java.io.OutputStream;
3431
import java.lang.invoke.MethodHandles;
3532
import org.apache.solr.common.util.Utils;
36-
import org.apache.solr.logging.MDCLoggingContext;
37-
import org.apache.solr.util.tracing.TraceUtils;
3833
import org.eclipse.jetty.http.HttpHeader;
3934
import org.slf4j.Logger;
4035
import org.slf4j.LoggerFactory;
@@ -124,51 +119,6 @@ public void close() {
124119
};
125120
}
126121

127-
/**
128-
* Sets up tracing for an HTTP request. Perhaps should be converted to a servlet filter at some
129-
* point.
130-
*
131-
* @param request The request to limit
132-
* @param response The associated response
133-
* @param tracedExecution the executed code
134-
*/
135-
static void traceHttpRequestExecution2(
136-
HttpServletRequest request, HttpServletResponse response, Runnable tracedExecution)
137-
throws ServletException, IOException {
138-
Context context = TraceUtils.extractContext(request);
139-
Span span = TraceUtils.startHttpRequestSpan(request, context);
140-
141-
final Thread currentThread = Thread.currentThread();
142-
final String oldThreadName = currentThread.getName();
143-
try (var scope = context.with(span).makeCurrent()) {
144-
assert scope != null; // prevent javac warning about scope being unused
145-
TraceUtils.setSpan(request, span);
146-
TraceUtils.ifValidTraceId(
147-
span, s -> MDCLoggingContext.setTracerId(s.getSpanContext().getTraceId()));
148-
String traceId = MDCLoggingContext.getTraceId();
149-
if (traceId != null) {
150-
currentThread.setName(oldThreadName + "-" + traceId);
151-
}
152-
tracedExecution.run();
153-
} catch (ExceptionWhileTracing e) {
154-
if (e.e instanceof ServletException) {
155-
throw (ServletException) e.e;
156-
}
157-
if (e.e instanceof IOException) {
158-
throw (IOException) e.e;
159-
}
160-
if (e.e instanceof RuntimeException) {
161-
throw (RuntimeException) e.e;
162-
} else {
163-
throw new RuntimeException(e.e);
164-
}
165-
} finally {
166-
currentThread.setName(oldThreadName);
167-
TraceUtils.setHttpStatus(span, response.getStatus());
168-
span.end();
169-
}
170-
}
171-
172122
// we make sure we read the full client request so that the client does
173123
// not hit a connection reset and we can reuse the
174124
// connection - see SOLR-8453 and SOLR-8683
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.solr.servlet;
19+
20+
import io.opentelemetry.api.trace.Span;
21+
import io.opentelemetry.context.Context;
22+
import jakarta.servlet.FilterChain;
23+
import jakarta.servlet.ServletException;
24+
import jakarta.servlet.http.HttpFilter;
25+
import jakarta.servlet.http.HttpServletRequest;
26+
import jakarta.servlet.http.HttpServletResponse;
27+
import java.io.IOException;
28+
import org.apache.solr.logging.MDCLoggingContext;
29+
import org.apache.solr.util.tracing.TraceUtils;
30+
31+
/**
32+
* Filter for distributed tracing. This filter creates a span for this request. While this filter
33+
* could be replaced, the replacement must supply an instance of io.opentelemetry.api.trace.Span for
34+
* use in the rest of solr.
35+
*/
36+
public class TracingFilter extends HttpFilter {
37+
38+
@Override
39+
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
40+
throws IOException, ServletException {
41+
Context context = TraceUtils.extractContext(req);
42+
Span span = TraceUtils.startHttpRequestSpan(req, context);
43+
44+
final Thread currentThread = Thread.currentThread();
45+
final String oldThreadName = currentThread.getName();
46+
try (var scope = context.with(span).makeCurrent()) {
47+
assert scope != null; // prevent javac warning about scope being unused
48+
TraceUtils.setSpan(req, span);
49+
TraceUtils.ifValidTraceId(
50+
span, s -> MDCLoggingContext.setTracerId(s.getSpanContext().getTraceId()));
51+
String traceId = MDCLoggingContext.getTraceId();
52+
if (traceId != null) {
53+
currentThread.setName(oldThreadName + "-" + traceId);
54+
}
55+
chain.doFilter(req, res);
56+
} finally {
57+
currentThread.setName(oldThreadName);
58+
TraceUtils.setHttpStatus(span, res.getStatus());
59+
span.end();
60+
}
61+
}
62+
}

solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.apache.solr.servlet.RateLimitFilter;
6666
import org.apache.solr.servlet.RequiredSolrRequestFilter;
6767
import org.apache.solr.servlet.SolrDispatchFilter;
68+
import org.apache.solr.servlet.TracingFilter;
6869
import org.apache.solr.util.SocketProxy;
6970
import org.apache.solr.util.TimeOut;
7071
import org.apache.solr.util.configuration.SSLConfigurationsFactory;
@@ -117,6 +118,7 @@ public class JettySolrRunner {
117118
volatile FilterHolder requiredFilter;
118119
volatile FilterHolder rateLimitFilter;
119120
volatile FilterHolder dispatchFilter;
121+
private FilterHolder tracingFilter;
120122

121123
private int jettyPort = -1;
122124

@@ -421,6 +423,10 @@ public void contextInitialized(ServletContextEvent event) {
421423
rateLimitFilter = root.getServletHandler().newFilterHolder(Source.EMBEDDED);
422424
rateLimitFilter.setHeldClass(RateLimitFilter.class);
423425

426+
// Ratelimit Requests
427+
tracingFilter = root.getServletHandler().newFilterHolder(Source.EMBEDDED);
428+
tracingFilter.setHeldClass(TracingFilter.class);
429+
424430
// This is our main workhorse
425431
dispatchFilter = root.getServletHandler().newFilterHolder(Source.EMBEDDED);
426432
dispatchFilter.setHeldClass(SolrDispatchFilter.class);
@@ -429,6 +435,7 @@ public void contextInitialized(ServletContextEvent event) {
429435
root.addFilter(pathExcludeFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
430436
root.addFilter(requiredFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
431437
root.addFilter(rateLimitFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
438+
root.addFilter(tracingFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
432439
root.addFilter(dispatchFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
433440

434441
// Default servlet as a fall-through

solr/webapp/web/WEB-INF/web.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@
6464
<url-pattern>/*</url-pattern>
6565
</filter-mapping>
6666

67+
<filter>
68+
<filter-name>TracingFilter</filter-name>
69+
<filter-class>org.apache.solr.servlet.TracingFilter</filter-class>
70+
</filter>
71+
72+
<filter-mapping>
73+
<filter-name>TracingFilter</filter-name>
74+
<url-pattern>/*</url-pattern>
75+
</filter-mapping>
76+
6777
<filter>
6878
<filter-name>SolrRequestFilter</filter-name>
6979
<filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class>

0 commit comments

Comments
 (0)