Skip to content

Commit 24e52c6

Browse files
authored
Starts 128-bit traces when spring.sleuth.traceId128=true (#455) (#456)
This adds autoconfiguration to create 128-bit traces when `spring.sleuth.traceId128=true`.
1 parent b0c8f26 commit 24e52c6

File tree

4 files changed

+160
-14
lines changed

4 files changed

+160
-14
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2013-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.sleuth.autoconfig;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
/**
22+
* Sleuth settings
23+
*
24+
* @since 1.0.11
25+
*/
26+
@ConfigurationProperties("spring.sleuth")
27+
public class SleuthProperties {
28+
/** When true, generate 128-bit trace IDs instead of 64-bit ones. */
29+
private boolean traceId128 = false;
30+
31+
public boolean isTraceId128() {
32+
return this.traceId128;
33+
}
34+
35+
public void setTraceId128(boolean traceId128) {
36+
this.traceId128 = traceId128;
37+
}
38+
}

spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Random;
2020

21+
import org.springframework.beans.factory.annotation.Autowired;
2122
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2223
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2324
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -44,8 +45,10 @@
4445
*/
4546
@Configuration
4647
@ConditionalOnProperty(value="spring.sleuth.enabled", matchIfMissing=true)
47-
@EnableConfigurationProperties(TraceKeys.class)
48+
@EnableConfigurationProperties({TraceKeys.class, SleuthProperties.class})
4849
public class TraceAutoConfiguration {
50+
@Autowired
51+
SleuthProperties properties;
4952

5053
@Bean
5154
@ConditionalOnMissingBean
@@ -65,7 +68,7 @@ public DefaultTracer sleuthTracer(Sampler sampler, Random random,
6568
SpanNamer spanNamer, SpanLogger spanLogger,
6669
SpanReporter spanReporter) {
6770
return new DefaultTracer(sampler, random, spanNamer, spanLogger,
68-
spanReporter);
71+
spanReporter, this.properties.isTraceId128());
6972
}
7073

7174
@Bean

spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTracer.java

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.util.Random;
2020
import java.util.concurrent.Callable;
21-
2221
import org.springframework.cloud.sleuth.Sampler;
2322
import org.springframework.cloud.sleuth.Span;
2423
import org.springframework.cloud.sleuth.SpanNamer;
@@ -47,13 +46,21 @@ public class DefaultTracer implements Tracer {
4746

4847
private final SpanReporter spanReporter;
4948

50-
public DefaultTracer(Sampler defaultSampler, Random random, SpanNamer spanNamer, SpanLogger spanLogger,
51-
SpanReporter spanReporter) {
49+
private final boolean traceId128;
50+
51+
public DefaultTracer(Sampler defaultSampler, Random random, SpanNamer spanNamer,
52+
SpanLogger spanLogger, SpanReporter spanReporter) {
53+
this(defaultSampler, random, spanNamer, spanLogger, spanReporter, false);
54+
}
55+
56+
public DefaultTracer(Sampler defaultSampler, Random random, SpanNamer spanNamer,
57+
SpanLogger spanLogger, SpanReporter spanReporter, boolean traceId128) {
5258
this.defaultSampler = defaultSampler;
5359
this.random = random;
5460
this.spanNamer = spanNamer;
5561
this.spanLogger = spanLogger;
5662
this.spanReporter = spanReporter;
63+
this.traceId128 = traceId128;
5764
}
5865

5966
@Override
@@ -77,11 +84,14 @@ public Span createSpan(String name, Sampler sampler) {
7784
}
7885
else {
7986
long id = createId();
80-
span = Span.builder().name(name).traceId(id).spanId(id).build();
87+
span = Span.builder().name(name)
88+
.traceIdHigh(this.traceId128 ? createId() : 0L)
89+
.traceId(id)
90+
.spanId(id).build();
8191
if (sampler == null) {
8292
sampler = this.defaultSampler;
8393
}
84-
span = sampledSpan(name, id, span, sampler);
94+
span = sampledSpan(span, sampler);
8595
this.spanLogger.logStartedSpan(null, span);
8696
}
8797
return continueSpan(span);
@@ -139,26 +149,39 @@ public void apply(Span span) {
139149
protected Span createChild(Span parent, String name) {
140150
long id = createId();
141151
if (parent == null) {
142-
Span span = Span.builder().name(name).traceId(id).spanId(id).build();
143-
span = sampledSpan(name, id, span, this.defaultSampler);
152+
Span span = Span.builder().name(name)
153+
.traceIdHigh(this.traceId128 ? createId() : 0L)
154+
.traceId(id)
155+
.spanId(id).build();
156+
span = sampledSpan(span, this.defaultSampler);
144157
this.spanLogger.logStartedSpan(null, span);
145158
return span;
146159
}
147160
else {
148161
if (!isTracing()) {
149162
SpanContextHolder.push(parent, true);
150163
}
151-
Span span = Span.builder().name(name).traceId(parent.getTraceId()).parent(parent.getSpanId()).spanId(id)
152-
.processId(parent.getProcessId()).savedSpan(parent).exportable(parent.isExportable()).build();
164+
Span span = Span.builder().name(name)
165+
.traceIdHigh(parent.getTraceIdHigh())
166+
.traceId(parent.getTraceId()).parent(parent.getSpanId()).spanId(id)
167+
.processId(parent.getProcessId()).savedSpan(parent)
168+
.exportable(parent.isExportable())
169+
.build();
153170
this.spanLogger.logStartedSpan(parent, span);
154171
return span;
155172
}
156173
}
157174

158-
private Span sampledSpan(String name, long id, Span span, Sampler sampler) {
175+
private Span sampledSpan(Span span, Sampler sampler) {
159176
if (!sampler.isSampled(span)) {
160-
// Non-exportable so we keep the trace but not other data
161-
return Span.builder().begin(span.getBegin()).name(name).traceId(id).spanId(id).exportable(false).build();
177+
// Copy everything, except set exportable to false
178+
return Span.builder()
179+
.begin(span.getBegin())
180+
.traceIdHigh(span.getTraceIdHigh())
181+
.traceId(span.getTraceId())
182+
.spanId(span.getSpanId())
183+
.name(span.getName())
184+
.exportable(false).build();
162185
}
163186
return span;
164187
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Copyright 2015-2016 The OpenZipkin Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
package org.springframework.cloud.sleuth.autoconfig;
15+
16+
import org.junit.After;
17+
import org.junit.Test;
18+
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
19+
import org.springframework.cloud.sleuth.Span;
20+
import org.springframework.cloud.sleuth.Tracer;
21+
import org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration;
22+
import org.springframework.cloud.sleuth.sampler.NeverSampler;
23+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
24+
25+
import static org.assertj.core.api.Assertions.assertThat;
26+
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
27+
28+
public class TraceAutoConfigurationTest {
29+
30+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
31+
32+
@After
33+
public void close() {
34+
context.close();
35+
}
36+
37+
@Test
38+
public void defaultsTo64BitTraceId() {
39+
context = new AnnotationConfigApplicationContext();
40+
context.register(
41+
PropertyPlaceholderAutoConfiguration.class,
42+
SleuthLogAutoConfiguration.class,
43+
TraceAutoConfiguration.class
44+
);
45+
context.refresh();
46+
Tracer tracer = context.getBean(Tracer.class);
47+
48+
Span span = null;
49+
try {
50+
span = tracer.createSpan("foo", NeverSampler.INSTANCE);
51+
assertThat(span.getTraceIdHigh()).isEqualTo(0L);
52+
assertThat(span.getTraceId()).isNotEqualTo(0L);
53+
} finally {
54+
if (span != null){
55+
tracer.close(span);
56+
}
57+
}
58+
}
59+
60+
@Test
61+
public void optInto128BitTraceId() {
62+
addEnvironment(context, "spring.sleuth.traceId128:true");
63+
context.register(
64+
PropertyPlaceholderAutoConfiguration.class,
65+
SleuthLogAutoConfiguration.class,
66+
TraceAutoConfiguration.class
67+
);
68+
context.refresh();
69+
Tracer tracer = context.getBean(Tracer.class);
70+
71+
Span span = null;
72+
try {
73+
span = tracer.createSpan("foo", NeverSampler.INSTANCE);
74+
assertThat(span.getTraceIdHigh()).isNotEqualTo(0L);
75+
assertThat(span.getTraceId()).isNotEqualTo(0L);
76+
} finally {
77+
if (span != null){
78+
tracer.close(span);
79+
}
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)