GoogleCloudPlatform / GoogleCloudPlatform/spring-cloud-gcp

Duplicate spans in GCP with default configuration

Open
#4,055 0 comments 0 reactions 0 assignees View on GitHub
priority: p3 trace type: bug
Dominant language
Java
Stars
551
Forks
349
Avg merge
1d 13h
Merged PRs (30d)
14

Description

When deploying a very simple Spring Boot application with gcp traces enabled, every trace will be duplicated.

Dependencies
```
dependencies {
annotationProcessor platform(SpringBootPlugin.BOM_COORDINATES) //3.5.4
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

implementation platform(SpringBootPlugin.BOM_COORDINATES) //3.5.4
implementation('org.springframework.boot:spring-boot-starter-web')

implementation platform("com.google.cloud:spring-cloud-gcp-dependencies:7.1.0")
implementation 'com.google.cloud:spring-cloud-gcp-starter-logging'
implementation 'com.google.cloud:spring-cloud-gcp-starter-trace'
}
```
and an application.yaml file:
```
spring:
cloud:
gcp:
project-id: project-id
application:
name: server

server:
port: 8080

management:
tracing:
sampling:
probability: 1
```

Deploying this on a GKE cluster will result in duplicate spans

Image

I found out that the auto-configuration will create 2 `SpanHandler` beans. 1 by `StackdriverTraceAutoConfiguration` and the other by `ZipkinConfigurations.BraveConfiguration`. I assume this is because Spring-boot will validate `ConditionalOnMissingBean` based on the declared bean class in this case `SpanHandler` vs `AsyncZipkinSpanHandler`.

Also in the test `StackdriverTraceAutoConfigurationTests` you can see that this `ZipkinAutoConfiguration.class ` is missing.

```
AutoConfigurations.of(
StackdriverTraceAutoConfiguration.class,
GcpContextAutoConfiguration.class,
BraveAutoConfiguration.class,
RefreshAutoConfiguration.class))
.withUserConfiguration(MockConfiguration.class)
```

If you add add this class the test will fail. The auto-config `StackdriverTraceAutoConfiguration` declares that this `ZipkinAutoConfiguration.class` is still allowed to run afterwards.

```
@AutoConfiguration
@EnableConfigurationProperties({GcpTraceProperties.class})
@ConditionalOnProperty(
value = {"spring.cloud.gcp.trace.enabled"},
matchIfMissing = true)
@ConditionalOnClass(StackdriverSender.class)
@AutoConfigureBefore({BraveAutoConfiguration.class, ZipkinAutoConfiguration.class})
public class StackdriverTraceAutoConfiguration
```

I would propose to change the method `public SpanHandler stackdriverSpanHandler(` in `StackdriverTraceAutoConfiguration.class` to `public AsyncZipkinSpanHandler stackdriverSpanHandler(` this will make sure the `@ConditionalOnMissingBean` will not create another AsyncZipkinSpanHandler bean.

In the meantime a workaround is available, by turning explicitly turn off zipkin export tracing in the application config like:
```
spring:
cloud:
gcp:
project-id: project-id
application:
name: server

server:
port: 8080

management:
zipkin:
tracing:
export:
enabled: false
tracing:
sampling:
probability: 1
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.