Skip to content

Commit c65d7ac

Browse files
committed
Otel optimizations I
1 parent bc6db6a commit c65d7ac

File tree

5 files changed

+316
-39
lines changed

5 files changed

+316
-39
lines changed

extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/OpenTelemetryUtil.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import java.util.LinkedHashMap;
66
import java.util.List;
77
import java.util.Map;
8-
import java.util.Map.Entry;
9-
import java.util.Set;
108

119
import io.opentelemetry.api.trace.Span;
1210
import io.opentelemetry.api.trace.SpanContext;
@@ -19,7 +17,6 @@ public final class OpenTelemetryUtil {
1917
public static final String SPAN_ID = "spanId";
2018
public static final String SAMPLED = "sampled";
2119
public static final String PARENT_ID = "parentId";
22-
private static final Set<String> SPAN_DATA_KEYS = Set.of(TRACE_ID, SPAN_ID, SAMPLED, PARENT_ID);
2320

2421
private OpenTelemetryUtil() {
2522
}
@@ -53,22 +50,28 @@ public static Map<String, String> convertKeyValueListToMap(List<String> headers)
5350

5451
/**
5552
* Sets MDC data by using the current span from the context.
53+
* <p>
54+
* This method is in the hot path and was optimized to not use getSpanData()
5655
*
5756
* @param context opentelemetry context
5857
* @param vertxContext vertx context
5958
*/
6059
public static void setMDCData(Context context, io.vertx.core.Context vertxContext) {
61-
setMDCData(getSpanData(context), vertxContext);
62-
}
63-
64-
public static void setMDCData(Map<String, String> spanData, io.vertx.core.Context vertxContext) {
65-
if (spanData == null) {
60+
if (context == null) {
6661
return;
6762
}
6863

69-
for (Entry<String, String> entry : spanData.entrySet()) {
70-
if (SPAN_DATA_KEYS.contains(entry.getKey())) {
71-
VertxMDC.INSTANCE.put(entry.getKey(), entry.getValue(), vertxContext);
64+
Span span = Span.fromContextOrNull(context);
65+
if (span != null) {
66+
SpanContext spanContext = span.getSpanContext();
67+
VertxMDC.INSTANCE.put(SPAN_ID, spanContext.getSpanId(), vertxContext);
68+
VertxMDC.INSTANCE.put(TRACE_ID, spanContext.getTraceId(), vertxContext);
69+
VertxMDC.INSTANCE.put(SAMPLED, Boolean.toString(spanContext.isSampled()), vertxContext);
70+
if (span instanceof ReadableSpan) {
71+
SpanContext parentSpanContext = ((ReadableSpan) span).getParentSpanContext();
72+
if (parentSpanContext != null && parentSpanContext.isValid()) {
73+
VertxMDC.INSTANCE.put(PARENT_ID, parentSpanContext.getSpanId(), vertxContext);
74+
}
7275
}
7376
}
7477
}
@@ -83,7 +86,7 @@ public static Map<String, String> getSpanData(Context context) {
8386
return Collections.emptyMap();
8487
}
8588
Span span = Span.fromContextOrNull(context);
86-
Map<String, String> spanData = new HashMap<>();
89+
Map<String, String> spanData = new HashMap<>(4, 1f);
8790
if (span != null) {
8891
SpanContext spanContext = span.getSpanContext();
8992
spanData.put(SPAN_ID, spanContext.getSpanId());

extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/QuarkusContextStorage.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import static io.quarkus.vertx.core.runtime.context.VertxContextSafetyToggle.setContextSafe;
44
import static io.smallrye.common.vertx.VertxContext.isDuplicatedContext;
55

6-
import java.util.Map;
7-
86
import org.jboss.logging.Logger;
97

108
import io.opentelemetry.context.Context;
@@ -66,8 +64,7 @@ public Scope attach(io.vertx.core.Context vertxContext, Context toAttach) {
6664
return Scope.noop();
6765
}
6866
vertxContext.putLocal(OTEL_CONTEXT, toAttach);
69-
final Map<String, String> spanDataToAttach = OpenTelemetryUtil.getSpanData(toAttach);
70-
OpenTelemetryUtil.setMDCData(spanDataToAttach, vertxContext);
67+
OpenTelemetryUtil.setMDCData(toAttach, vertxContext);
7168

7269
return new Scope() {
7370

@@ -77,7 +74,7 @@ public void close() {
7774
if (before != toAttach) {
7875
log.info("Context in storage not the expected context, Scope.close was not called correctly. Details:" +
7976
" OTel context before: " + OpenTelemetryUtil.getSpanData(before) +
80-
". OTel context toAttach: " + spanDataToAttach);
77+
". OTel context toAttach: " + OpenTelemetryUtil.getSpanData(toAttach));
8178
}
8279

8380
if (beforeAttach == null) {

extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/DropTargetsSampler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String
3737

3838
if (spanKind.equals(SpanKind.SERVER)) {
3939
// HTTP_TARGET was split into url.path and url.query
40-
String path = attributes.get(URL_PATH);
4140
String query = attributes.get(URL_QUERY);
42-
String target = path + (query == null ? "" : "?" + query);
41+
String target = attributes.get(URL_PATH) + (query == null ? "" : "?" + query);
4342

4443
if (shouldDrop(target)) {
4544
return SamplingResult.drop();

extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/VertxUtil.java

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public final class VertxUtil {
99
private static final Pattern FORWARDED_FOR_PATTERN = Pattern.compile("for=\"?([^;,\"]+)\"?");
1010
private static final String FORWARDED = "Forwarded";
1111
private static final String COMMA_SPLITTER = ",";
12-
private static final String COLON_SPLITTER = ":";
12+
private static final char COLON_SPLITTER = ':';
1313
private static final int SPLIT_LIMIT = -1;
1414

1515
private VertxUtil() {
@@ -35,23 +35,6 @@ private static String getXForwardedHeaderValue(HttpServerRequest httpServerReque
3535
return xForwardedForHeader.split(COMMA_SPLITTER, SPLIT_LIMIT)[0];
3636
}
3737

38-
private static String getHostHeader(HttpServerRequest httpRequest) {
39-
String header = httpRequest.getHeader("host");
40-
if (header == null) {
41-
return null;
42-
}
43-
return header.split(COLON_SPLITTER, SPLIT_LIMIT)[0];
44-
}
45-
46-
private static String getHostPortHeader(HttpServerRequest httpRequest) {
47-
String header = httpRequest.getHeader("host");
48-
if (header == null) {
49-
return null;
50-
}
51-
String[] headerValues = header.split(COLON_SPLITTER, SPLIT_LIMIT);
52-
return headerValues.length > 1 ? headerValues[1] : null;
53-
}
54-
5538
public static String extractClientIP(HttpServerRequest httpServerRequest) {
5639
// Tries to fetch Forwarded first since X-Forwarded can be lost by a proxy
5740
// If Forwarded is not there tries to fetch the X-Forwarded-For header
@@ -69,15 +52,29 @@ public static String extractClientIP(HttpServerRequest httpServerRequest) {
6952
}
7053

7154
public static String extractRemoteHostname(HttpServerRequest httpRequest) {
72-
String hostname = getHostHeader(httpRequest);
55+
String header = httpRequest.getHeader("host");
56+
if (header == null) {
57+
return null;
58+
}
59+
60+
// localhost:8808, hostname localhost
61+
String hostname = beforeDelimiter(header, COLON_SPLITTER);
62+
7363
if (hostname != null) {
7464
return hostname;
7565
}
7666
return httpRequest.remoteAddress() != null ? httpRequest.remoteAddress().hostName() : null;
7767
}
7868

7969
public static Long extractRemoteHostPort(HttpServerRequest httpRequest) {
80-
String portString = getHostPortHeader(httpRequest);
70+
String header = httpRequest.getHeader("host");
71+
if (header == null) {
72+
return null;
73+
}
74+
75+
// localhost:8808, port 8080
76+
String portString = afterDelimiter(header, COLON_SPLITTER);
77+
8178
if (portString != null) {
8279
try {
8380
return Long.parseLong(portString);
@@ -90,4 +87,27 @@ public static Long extractRemoteHostPort(HttpServerRequest httpRequest) {
9087
}
9188
return null;
9289
}
90+
91+
private static String beforeDelimiter(String str, char delimiter) {
92+
if (str == null || str.isEmpty()) {
93+
return "";
94+
}
95+
int index = str.indexOf(delimiter);
96+
return (index >= 0) ? str.substring(0, index) : str;
97+
}
98+
99+
private static String afterDelimiter(String str, char delimiter) {
100+
if (str == null || str.isEmpty()) {
101+
return "";
102+
}
103+
104+
int index = str.indexOf(delimiter);
105+
if (index < 0) {
106+
return null;
107+
} else if (index >= 0 && index + 1 < str.length()) {
108+
return str.substring(index + 1);
109+
} else {
110+
return "";
111+
}
112+
}
93113
}

0 commit comments

Comments
 (0)