diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java index 1a0fb0511..7fcbdd537 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java @@ -45,32 +45,29 @@ public class SpringAwareManagedChannelBuilder { } public ManagedChannelBuilder forAddress(String name, int port) { - ManagedChannelBuilder builder = ManagedChannelBuilder.forAddress(name, port); - - if (this.customizers != null) { - this.customizers.stream() - .forEach(customizer -> customizer.customize(builder)); - } + customize(builder); return builder; } public ManagedChannelBuilder forTarget(String target) { ManagedChannelBuilder builder = ManagedChannelBuilder.forTarget(target); - if (this.customizers != null) { - this.customizers.stream() - .forEach(customizer -> customizer.customize(builder)); - } + customize(builder); return builder; } public ManagedChannelBuilder inProcessChannelBuilder(String serverName) { ManagedChannelBuilder builder = InProcessChannelBuilder.forName(serverName); - if (this.customizers != null) { - this.customizers.stream() - .forEach(customizer -> customizer.customize(builder)); - } + customize(builder); return builder; } + private void customize(ManagedChannelBuilder builder) { + if (this.customizers != null) { + for (GrpcManagedChannelBuilderCustomizer customizer : this.customizers) { + customizer.customize(builder); + } + } + } + } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java index 4381593ac..862cd9e17 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java @@ -17,8 +17,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Optional; import brave.Span; import brave.Tracer; @@ -313,15 +311,14 @@ class MessageListenerMethodInterceptor return invocation.proceed(); } Object[] arguments = invocation.getArguments(); - Optional record = Arrays.stream(arguments) - .filter(o -> o instanceof ConsumerRecord).findFirst(); - if (!record.isPresent()) { + Object record = record(arguments); + if (record == null) { return invocation.proceed(); } if (log.isDebugEnabled()) { log.debug("Wrapping onMessage call"); } - Span span = this.kafkaTracing.nextSpan((ConsumerRecord) record.get()) + Span span = this.kafkaTracing.nextSpan((ConsumerRecord) record) .name("on-message").start(); try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) { return invocation.proceed(); @@ -339,6 +336,15 @@ class MessageListenerMethodInterceptor } } + private Object record(Object[] arguments) { + for (Object object : arguments) { + if (object instanceof ConsumerRecord) { + return object; + } + } + return null; + } + } class TracingJmsBeanPostProcessor implements BeanPostProcessor { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java index 77809254f..8c77eacfd 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java @@ -59,12 +59,12 @@ class SleuthHttpClientParser extends HttpClientParser { URI uri = URI.create(url); addRequestTags(customizer, url, uri.getHost(), uri.getPath(), adapter.method(req)); - this.traceKeys.getHttp().getHeaders().forEach(((s) -> { - String headerValue = adapter.requestHeader(req, s); + for (String header : this.traceKeys.getHttp().getHeaders()) { + String headerValue = adapter.requestHeader(req, header); if (headerValue != null) { - customizer.tag(key(s), headerValue); + customizer.tag(key(header), headerValue); } - })); + } } private String key(String key) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 39aa2a645..98ac71ac6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -20,8 +20,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.StringJoiner; import java.util.regex.Pattern; -import java.util.stream.Collectors; import brave.Tracing; @@ -32,7 +32,6 @@ import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortT import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.actuate.endpoint.EndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -67,10 +66,18 @@ public class TraceWebAutoConfiguration { @Bean @ConditionalOnMissingBean SkipPatternProvider sleuthSkipPatternProvider() { - return () -> Pattern - .compile(this.patterns.stream().map(SingleSkipPattern::skipPattern) - .filter(Optional::isPresent).map(Optional::get) - .map(Pattern::pattern).collect(Collectors.joining("|"))); + return () -> { + StringJoiner joiner = new StringJoiner("|"); + for (SingleSkipPattern pattern : this.patterns) { + Optional skipPattern = pattern.skipPattern(); + if (skipPattern.isPresent()) { + Pattern pattern1 = skipPattern.get(); + String s = pattern1.pattern(); + joiner.add(s); + } + } + return Pattern.compile(joiner.toString()); + }; } @Configuration @@ -116,22 +123,30 @@ public class TraceWebAutoConfiguration { WebEndpointProperties webEndpointProperties, EndpointsSupplier endpointsSupplier) { Collection endpoints = endpointsSupplier.getEndpoints(); - if (endpoints.isEmpty()) { return Optional.empty(); } - String basePath = webEndpointProperties.getBasePath(); - String pattern = endpoints.stream().map(PathMappedEndpoint::getRootPath) - .map(path -> path + "|" + path + "/.*") - .collect(Collectors.joining("|", getPathPrefix(contextPath, basePath), - getPathSuffix(contextPath, basePath))); + String pattern = patternFromEndpoints(contextPath, endpoints, basePath); if (StringUtils.hasText(pattern)) { return Optional.of(Pattern.compile(pattern)); } return Optional.empty(); } + private static String patternFromEndpoints(String contextPath, + Collection endpoints, String basePath) { + StringJoiner joiner = new StringJoiner("|", + getPathPrefix(contextPath, basePath), + getPathSuffix(contextPath, basePath)); + for (ExposableWebEndpoint endpoint : endpoints) { + String path = endpoint.getRootPath(); + String paths = path + "|" + path + "/.*"; + joiner.add(paths); + } + return joiner.toString(); + } + private static String getPathPrefix(String contextPath, String actuatorBasePath) { String result = ""; if (StringUtils.hasText(contextPath)) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java index 096b4c9d8..dab4d2d81 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -153,10 +153,11 @@ class HttpClientBeanPostProcessor implements BeanPostProcessor { @Override public void accept(HttpClientRequest req, Connection connection) { - if (propagation().keys().stream() - .anyMatch(key -> req.requestHeaders().contains(key))) { - // request already instrumented - return; + // request already instrumented + for (String key : propagation().keys()) { + if (req.requestHeaders().contains(key)) { + return; + } } AtomicReference reference = req.currentContext() .getOrDefault(AtomicReference.class, new AtomicReference()); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index 4408c148c..d23a6c155 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -16,6 +16,9 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import java.util.List; +import java.util.Map; + import brave.Span; import brave.Tracer; import brave.http.HttpClientHandler; @@ -58,10 +61,20 @@ final class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { exchange.getAttributes().put(SPAN_ATTRIBUTE, span); HttpHeaders headersWithInput = new HttpHeaders(); headersWithInput.addAll(input); - builder.build().getHeaders().forEach(headersWithInput::put); + addHeadersWithInput(builder, headersWithInput); return headersWithInput; } + private void addHeadersWithInput(ServerHttpRequest.Builder builder, + HttpHeaders headersWithInput) { + for (Map.Entry> entry : builder.build().getHeaders() + .entrySet()) { + String key = entry.getKey(); + List value = entry.getValue(); + headersWithInput.put(key, value); + } + } + @Override public boolean supports(Type type) { return type.equals(Type.REQUEST); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index 2ef8eca9e..2d4631ffa 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -100,13 +100,23 @@ final class TraceWebClientBeanPostProcessor implements BeanPostProcessor { private Consumer> addTraceExchangeFilterFunctionIfNotPresent() { return functions -> { - if (functions.stream() - .noneMatch(f -> f instanceof TraceExchangeFilterFunction)) { + boolean noneMatch = noneMatchTraceExchangeFunction(functions); + if (noneMatch) { functions.add(new TraceExchangeFilterFunction(this.beanFactory)); } }; } + private boolean noneMatchTraceExchangeFunction( + List functions) { + for (ExchangeFilterFunction function : functions) { + if (function instanceof TraceExchangeFilterFunction) { + return false; + } + } + return true; + } + } final class TraceExchangeFilterFunction implements ExchangeFilterFunction { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java index a0fe3caf0..c97ffb22f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java @@ -86,7 +86,8 @@ final class Slf4jScopeDecorator implements CurrentTraceContext.ScopeDecorator { final String legacyPreviousParentId = MDC.get(LEGACY_PARENT_ID_NAME); final String legacyPreviousSpanId = MDC.get(LEGACY_SPAN_ID_NAME); final String legacySpanExportable = MDC.get(LEGACY_EXPORTABLE_NAME); - final List> previousMdc = Stream + final List> previousMdc = + Stream .concat(whitelistedBaggageKeysWithValue(currentSpan), whitelistedPropagationKeysWithValue(currentSpan)) .map((s) -> new AbstractMap.SimpleEntry<>(s, MDC.get(s))) @@ -149,7 +150,9 @@ final class Slf4jScopeDecorator implements CurrentTraceContext.ScopeDecorator { replace(LEGACY_PARENT_ID_NAME, legacyPreviousParentId); replace(LEGACY_SPAN_ID_NAME, legacyPreviousSpanId); replace(LEGACY_EXPORTABLE_NAME, legacySpanExportable); - previousMdc.forEach((e) -> replace(e.getKey(), e.getValue())); + for (AbstractMap.SimpleEntry entry : previousMdc) { + replace(entry.getKey(), entry.getValue()); + } } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java index 4491009c9..c6bc5c6f6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java @@ -17,8 +17,8 @@ package org.springframework.cloud.sleuth.propagation; import java.util.AbstractMap; -import java.util.Collection; -import java.util.stream.Stream; +import java.util.Arrays; +import java.util.List; import brave.handler.FinishedSpanHandler; import brave.handler.MutableSpan; @@ -50,14 +50,18 @@ public class TagPropagationFinishedSpanHandler extends FinishedSpanHandler { @Override public boolean handle(TraceContext context, MutableSpan span) { - Stream.of(this.sleuthProperties.getBaggageKeys(), - this.sleuthProperties.getPropagationKeys()).flatMap(Collection::stream) - .filter(key -> this.tagPropagationProperties.getWhitelistedKeys() - .contains(key)) - .map(baggageItemKey -> new AbstractMap.SimpleEntry<>(baggageItemKey, - ExtraFieldPropagation.get(context, baggageItemKey))) - .filter(entry -> nonNull(entry.getValue())) - .forEach(entry -> span.tag(entry.getKey(), entry.getValue())); + for (List strings : Arrays.asList(this.sleuthProperties.getBaggageKeys(), + this.sleuthProperties.getPropagationKeys())) { + for (String key : strings) { + if (this.tagPropagationProperties.getWhitelistedKeys().contains(key)) { + AbstractMap.SimpleEntry entry = new AbstractMap.SimpleEntry<>( + key, ExtraFieldPropagation.get(context, key)); + if (nonNull(entry.getValue())) { + span.tag(entry.getKey(), entry.getValue()); + } + } + } + } return true; } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java index 8314c2c15..3e4960146 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java @@ -32,10 +32,11 @@ public class SleuthTagPropagationAutoConfigurationTests { @Test public void shouldCreateHandlerByDefault() { - this.contextRunner - .withUserConfiguration(TraceAutoConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(TagPropagationFinishedSpanHandler.class); - }); + this.contextRunner.withUserConfiguration(TraceAutoConfiguration.class) + .run((context) -> { + assertThat(context) + .hasSingleBean(TagPropagationFinishedSpanHandler.class); + }); } @Test @@ -63,12 +64,11 @@ public class SleuthTagPropagationAutoConfigurationTests { @Test public void shouldCreateHandlerWithYml() { - this.contextRunner - .withPropertyValues( - "spring.profiles.active=tag-propagation") + this.contextRunner.withPropertyValues("spring.profiles.active=tag-propagation") .withUserConfiguration(TraceAutoConfiguration.class).run((context) -> { assertThat(context) .hasSingleBean(TagPropagationFinishedSpanHandler.class); }); } + }