Added opt in for SocketAddress Mongo spans; fixes gh-2050

This commit is contained in:
Marcin Grzejszczak
2021-11-03 11:41:00 +01:00
parent b2df1ec742
commit 8620d399f4
11 changed files with 182 additions and 33 deletions

View File

@@ -59,6 +59,7 @@
|spring.sleuth.messaging.rabbit.enabled | `true` | Enable tracing of RabbitMQ.
|spring.sleuth.messaging.rabbit.remote-service-name | `rabbitmq` | Rabbit remote service name.
|spring.sleuth.mongodb.enabled | `true` | Enable tracing for MongoDb.
|spring.sleuth.mongodb.socket-address-span-customizer.enabled | `false` | Enable setting of SocketAddress information on the Mongo span.
|spring.sleuth.opentracing.enabled | `true` | Enables OpenTracing support.
|spring.sleuth.propagation.type | | Tracing context propagation types.
|spring.sleuth.quartz.enabled | `true` | Enable tracing for Quartz.

View File

@@ -752,6 +752,16 @@ and set `spring.sleuth.jdbc.datasource-proxy.query.enable-logging` to `true` to
In order to disable this instrumentation set `spring.sleuth.jdbc.enabled` to `false`.
[[sleuth-mongodb-integration]]
== MongoDB
This feature is available for all tracer implementations.
We're adding command listeners that wrap all commands in a span.
If you want to have additional socket address related tags on the span set the `spring.sleuth.mongodb.socket-address-span-customizer.enabled` to `true`.
In order to disable this instrumentation set ``spring.sleuth.mongodb.enabled`` to `false`.
[[sleuth-session-integration]]
== Spring Session

View File

@@ -59,8 +59,9 @@ import org.springframework.context.annotation.Configuration;
class BraveBridgeConfiguration {
@Bean
org.springframework.cloud.sleuth.Tracer braveTracer(brave.Tracer tracer) {
return new BraveTracer(tracer, new BraveBaggageManager());
org.springframework.cloud.sleuth.Tracer braveTracer(brave.Tracer tracer,
org.springframework.cloud.sleuth.CurrentTraceContext braveCurrentTraceContext) {
return new BraveTracer(tracer, braveCurrentTraceContext, new BraveBaggageManager());
}
@Bean

View File

@@ -16,8 +16,12 @@
package org.springframework.cloud.sleuth.autoconfig.instrument.mongodb;
import java.util.ArrayList;
import java.util.List;
import com.mongodb.MongoClientSettings;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
@@ -27,11 +31,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.cloud.sleuth.CurrentTraceContext;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceAllTypesMongoClientSettingsBuilderCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceMongoClientSettingsBuilderCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceMongoClusterIdSpanCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceMongoSocketAddressSpanCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceMongoSpanCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceReactiveMongoClientSettingsBuilderCustomizer;
import org.springframework.cloud.sleuth.instrument.mongodb.TraceSynchronousMongoClientSettingsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
@@ -57,8 +63,8 @@ public class TraceMongoDbAutoConfiguration {
@ConditionalOnMissingBean
@Conditional(EitherSynchronousOrReactiveContextProviderPresent.class)
TraceMongoClientSettingsBuilderCustomizer traceMongoClientSettingsBuilderCustomizer(Tracer tracer,
CurrentTraceContext currentTraceContext) {
return new TraceMongoClientSettingsBuilderCustomizer(tracer, currentTraceContext);
ObjectProvider<List<TraceMongoSpanCustomizer>> customizers) {
return new TraceMongoClientSettingsBuilderCustomizer(tracer, customizers.getIfAvailable(ArrayList::new));
}
@Bean
@@ -86,6 +92,22 @@ public class TraceMongoDbAutoConfiguration {
return new TraceAllTypesMongoClientSettingsBuilderCustomizer(tracer);
}
@Configuration(proxyBeanMethods = false)
static class MongoCustomizersConfiguration {
@Bean
TraceMongoSpanCustomizer traceMongoClusterIdSpanCustomizer() {
return new TraceMongoClusterIdSpanCustomizer();
}
@Bean
@ConditionalOnProperty("spring.sleuth.mongodb.socket-address-span-customizer.enabled")
TraceMongoSpanCustomizer traceMongoSocketAddressSpanCustomizer() {
return new TraceMongoSocketAddressSpanCustomizer();
}
}
static class EitherSynchronousOrReactiveContextProviderPresent extends AnyNestedCondition {
EitherSynchronousOrReactiveContextProviderPresent() {

View File

@@ -112,6 +112,12 @@
"type": "java.lang.Boolean",
"description": "Enable tracing for MongoDb.",
"defaultValue": true
},
{
"name": "spring.sleuth.mongodb.socket-address-span-customizer.enabled",
"type": "java.lang.Boolean",
"description": "Enable setting of SocketAddress information on the Mongo span.",
"defaultValue": false
},
{
"name": "spring.sleuth.rpc.enabled",

View File

@@ -43,6 +43,7 @@ public class BraveTracer implements Tracer {
private final CurrentTraceContext currentTraceContext;
@Deprecated
public BraveTracer(brave.Tracer tracer, BraveBaggageManager braveBaggageManager) {
this.tracer = tracer;
this.braveBaggageManager = braveBaggageManager;

View File

@@ -16,10 +16,11 @@
package org.springframework.cloud.sleuth.instrument.mongodb;
import java.util.List;
import com.mongodb.MongoClientSettings;
import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
import org.springframework.cloud.sleuth.CurrentTraceContext;
import org.springframework.cloud.sleuth.Tracer;
/**
@@ -32,16 +33,16 @@ public class TraceMongoClientSettingsBuilderCustomizer implements MongoClientSet
private final Tracer tracer;
private final CurrentTraceContext currentTraceContext;
private final List<TraceMongoSpanCustomizer> customizers;
public TraceMongoClientSettingsBuilderCustomizer(Tracer tracer, CurrentTraceContext currentTraceContext) {
public TraceMongoClientSettingsBuilderCustomizer(Tracer tracer, List<TraceMongoSpanCustomizer> customizers) {
this.tracer = tracer;
this.currentTraceContext = currentTraceContext;
this.customizers = customizers;
}
@Override
public void customize(MongoClientSettings.Builder clientSettingsBuilder) {
clientSettingsBuilder.addCommandListener(new TraceMongoCommandListener(this.tracer, this.currentTraceContext));
clientSettingsBuilder.addCommandListener(new TraceMongoCommandListener(this.tracer, this.customizers));
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.cloud.sleuth.instrument.mongodb;
import com.mongodb.connection.ConnectionDescription;
import com.mongodb.connection.ConnectionId;
import com.mongodb.event.CommandStartedEvent;
import org.springframework.cloud.sleuth.Span;
public class TraceMongoClusterIdSpanCustomizer implements TraceMongoSpanCustomizer {
public void customizeCommandStartSpan(CommandStartedEvent event, Span.Builder spanBuilder) {
ConnectionDescription connectionDescription = event.getConnectionDescription();
if (connectionDescription != null) {
ConnectionId connectionId = connectionDescription.getConnectionId();
if (connectionId != null) {
spanBuilder.tag("mongodb.cluster_id", connectionId.getServerId().getClusterId().getValue());
}
}
}
}

View File

@@ -16,15 +16,12 @@
package org.springframework.cloud.sleuth.instrument.mongodb;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.mongodb.MongoSocketException;
import com.mongodb.RequestContext;
import com.mongodb.connection.ConnectionDescription;
import com.mongodb.connection.ConnectionId;
import com.mongodb.event.CommandFailedEvent;
import com.mongodb.event.CommandListener;
import com.mongodb.event.CommandStartedEvent;
@@ -60,9 +57,12 @@ final class TraceMongoCommandListener implements CommandListener {
private final CurrentTraceContext currentTraceContext;
TraceMongoCommandListener(Tracer tracer, CurrentTraceContext currentTraceContext) {
private final List<TraceMongoSpanCustomizer> customizers;
TraceMongoCommandListener(Tracer tracer, List<TraceMongoSpanCustomizer> customizers) {
this.tracer = tracer;
this.currentTraceContext = currentTraceContext;
this.currentTraceContext = tracer.currentTraceContext();
this.customizers = customizers;
}
@Override
@@ -100,23 +100,7 @@ final class TraceMongoCommandListener implements CommandListener {
childSpanBuilder.tag("mongodb.collection", collectionName);
}
ConnectionDescription connectionDescription = event.getConnectionDescription();
if (connectionDescription != null) {
ConnectionId connectionId = connectionDescription.getConnectionId();
if (connectionId != null) {
childSpanBuilder.tag("mongodb.cluster_id", connectionId.getServerId().getClusterId().getValue());
}
try {
InetSocketAddress socketAddress = connectionDescription.getServerAddress().getSocketAddress();
childSpanBuilder.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
}
catch (MongoSocketException ignored) {
if (log.isDebugEnabled()) {
log.debug("Ignored exception when setting remote ip and port", ignored);
}
}
}
this.customizers.forEach(customizer -> customizer.customizeCommandStartSpan(event, childSpanBuilder));
Span childSpan = childSpanBuilder.start();
// TODO: What about retries? We might override the parent span

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.cloud.sleuth.instrument.mongodb;
import java.net.InetSocketAddress;
import com.mongodb.MongoSocketException;
import com.mongodb.connection.ConnectionDescription;
import com.mongodb.event.CommandStartedEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.sleuth.Span;
public class TraceMongoSocketAddressSpanCustomizer implements TraceMongoSpanCustomizer {
private static final Log log = LogFactory.getLog(TraceMongoClusterIdSpanCustomizer.class);
public void customizeCommandStartSpan(CommandStartedEvent event, Span.Builder spanBuilder) {
ConnectionDescription connectionDescription = event.getConnectionDescription();
if (connectionDescription != null) {
try {
InetSocketAddress socketAddress = connectionDescription.getServerAddress().getSocketAddress();
spanBuilder.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
}
catch (MongoSocketException ignored) {
if (log.isDebugEnabled()) {
log.debug("Ignored exception when setting remote ip and port", ignored);
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.cloud.sleuth.instrument.mongodb;
import com.mongodb.event.CommandStartedEvent;
import org.springframework.cloud.sleuth.Span;
/**
* Customizer for the child span wrapping the call to Mongo.
*
* @author Marcin Grzejszczak
* @since 3.1.0
*/
public interface TraceMongoSpanCustomizer {
/**
* Customizes the Span created from the {@link CommandStartedEvent}.
* @param commandStartedEvent event from Mongo
* @param spanBuilder span builder to customize
*/
void customizeCommandStartSpan(CommandStartedEvent commandStartedEvent, Span.Builder spanBuilder);
}