Skip to content

Commit c8f10d7

Browse files
committed
JAV-124 updated test case to ensure parent and child spans are linked
1 parent 65a5e88 commit c8f10d7

5 files changed

Lines changed: 135 additions & 26 deletions

File tree

handlers/handler-tracing-zipkin/src/main/java/io/servicecomb/tracing/zipkin/TracingConfiguration.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import brave.Tracing;
2525
import brave.context.log4j12.MDCCurrentTraceContext;
2626
import brave.http.HttpTracing;
27+
import brave.propagation.CurrentTraceContext;
2728
import io.servicecomb.config.DynamicProperties;
2829
import org.springframework.context.annotation.Bean;
2930
import org.springframework.context.annotation.Configuration;
@@ -45,18 +46,23 @@ Sender sender(DynamicProperties dynamicProperties) {
4546
}
4647

4748
@Bean
48-
Reporter<Span> reporter(Sender sender) {
49+
Reporter<Span> zipkinReporter(Sender sender) {
4950
return AsyncReporter.builder(sender).build();
5051
}
5152

5253
@Bean
53-
Tracing tracing(Reporter<Span> reporter, DynamicProperties dynamicProperties) {
54+
Tracing tracing(Reporter<Span> reporter, DynamicProperties dynamicProperties, CurrentTraceContext currentTraceContext) {
5455
return Tracing.newBuilder()
5556
.localServiceName(dynamicProperties.getStringProperty(CONFIG_SERVICE_NAME, DEFAULT_SERVICE_NAME))
56-
.currentTraceContext(MDCCurrentTraceContext.create()) // puts trace IDs into logs
57+
.currentTraceContext(currentTraceContext) // puts trace IDs into logs
5758
.reporter(reporter).build();
5859
}
5960

61+
@Bean
62+
CurrentTraceContext currentTraceContext() {
63+
return MDCCurrentTraceContext.create();
64+
}
65+
6066
@Bean
6167
HttpTracing httpTracing(Tracing tracing) {
6268
return HttpTracing.create(tracing);

integration-tests/test-common/src/test/java/io/servicecomb/tests/EmbeddedAppender.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
import java.io.IOException;
2121
import java.io.OutputStream;
2222
import java.io.OutputStreamWriter;
23-
import java.util.LinkedList;
24-
import java.util.List;
23+
import java.util.Collection;
24+
import java.util.LinkedHashSet;
2525
import java.util.Queue;
26+
import java.util.Set;
2627
import java.util.concurrent.ConcurrentLinkedQueue;
2728
import javax.annotation.Nonnull;
2829
import org.apache.log4j.ConsoleAppender;
@@ -34,7 +35,7 @@ public class EmbeddedAppender extends ConsoleAppender {
3435
private final Poller poller = new Poller(5000, 200);
3536

3637
public EmbeddedAppender() {
37-
super(new PatternLayout("%d{ABSOLUTE} [%X{traceId}/%X{spanId}] %-5p [%t] %C{2} (%F:%L) - %m%n"));
38+
super(new PatternLayout("%d{ABSOLUTE} [%X{traceId}/%X{spanId}/%X{parentId}] %-5p [%t] %C{2} (%F:%L) - %m%n"));
3839
}
3940

4041
@Override
@@ -43,8 +44,8 @@ protected OutputStreamWriter createWriter(OutputStream os) {
4344
return super.createWriter(new InMemoryOutputStream(events, os));
4445
}
4546

46-
public List<String> pollLogs(String regex) {
47-
final List<String> messages = new LinkedList<>();
47+
public Collection<String> pollLogs(String regex) {
48+
final Set<String> messages = new LinkedHashSet<>();
4849

4950
poller.assertEventually(() -> {
5051
for (String event : events) {

integration-tests/tracing-tests/src/test/java/io/servicecomb/tests/tracing/SomeTracedController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ public String world() throws InterruptedException {
5252
logger.info("in /world");
5353
Thread.sleep(random.nextInt(1000));
5454

55-
return "world";
55+
return "world, " + template.getForObject("cse://tracing-service/jaxrs/bonjour", String.class);
5656
}
5757
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2017 Huawei Technologies Co., Ltd
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 io.servicecomb.tests.tracing;
18+
19+
import brave.internal.HexCodec;
20+
import brave.propagation.CurrentTraceContext;
21+
import brave.propagation.TraceContext;
22+
import org.apache.log4j.MDC;
23+
import org.springframework.context.annotation.Bean;
24+
import org.springframework.context.annotation.Configuration;
25+
import org.springframework.context.annotation.Primary;
26+
27+
@Configuration
28+
class TraceContextConfig {
29+
30+
@Bean
31+
@Primary
32+
CurrentTraceContext traceContext() {
33+
return ParentAwareMDCCurrentTraceContext.create();
34+
}
35+
36+
private static class ParentAwareMDCCurrentTraceContext extends CurrentTraceContext {
37+
static ParentAwareMDCCurrentTraceContext create() {
38+
return new ParentAwareMDCCurrentTraceContext(new Default());
39+
}
40+
41+
private final CurrentTraceContext delegate;
42+
43+
ParentAwareMDCCurrentTraceContext(CurrentTraceContext delegate) {
44+
if (delegate == null) {
45+
throw new NullPointerException("delegate == null");
46+
}
47+
this.delegate = delegate;
48+
}
49+
50+
@Override
51+
public TraceContext get() {
52+
return delegate.get();
53+
}
54+
55+
@Override
56+
public Scope newScope(TraceContext currentSpan) {
57+
final Object previousTraceId = MDC.get("traceId");
58+
final Object previousSpanId = MDC.get("spanId");
59+
final Object previousParentId = MDC.get("parentId");
60+
61+
if (currentSpan != null) {
62+
MDC.put("traceId", currentSpan.traceIdString());
63+
MDC.put("spanId", HexCodec.toLowerHex(currentSpan.spanId()));
64+
if (currentSpan.parentId() != null) {
65+
MDC.put("parentId", HexCodec.toLowerHex(currentSpan.parentId()));
66+
}
67+
} else {
68+
MDC.remove("traceId");
69+
MDC.remove("spanId");
70+
MDC.remove("parentId");
71+
}
72+
73+
Scope scope = delegate.newScope(currentSpan);
74+
class MDCCurrentTraceContextScope implements Scope {
75+
@Override public void close() {
76+
scope.close();
77+
if (previousTraceId != null) {
78+
MDC.put("traceId", previousTraceId);
79+
} else {
80+
MDC.remove("traceId");
81+
}
82+
83+
if (previousSpanId != null) {
84+
MDC.put("spanId", previousSpanId);
85+
} else {
86+
MDC.remove("spanId");
87+
}
88+
89+
if (previousParentId != null) {
90+
MDC.put("parentId", previousParentId);
91+
} else {
92+
MDC.remove("parentId");
93+
}
94+
}
95+
}
96+
return new MDCCurrentTraceContextScope();
97+
}
98+
}
99+
}

integration-tests/tracing-tests/src/test/java/io/servicecomb/tests/tracing/ZipkinTracingIntegrationTest.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import io.servicecomb.tests.EmbeddedAppender;
3737
import io.servicecomb.tests.Log4jConfig;
3838
import java.net.URL;
39-
import java.util.List;
39+
import java.util.Collection;
40+
import java.util.Iterator;
4041
import java.util.concurrent.TimeUnit;
4142
import org.junit.Before;
4243
import org.junit.BeforeClass;
@@ -82,36 +83,38 @@ public void sendsTracingToConfiguredAddress() throws InterruptedException {
8283
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8080/hello", String.class);
8384

8485
assertThat(entity.getStatusCode(), is(OK));
85-
assertThat(entity.getBody(), is("hello world"));
86-
87-
entity = restTemplate.getForEntity("http://localhost:8080/jaxrs/bonjour", String.class);
88-
89-
assertThat(entity.getStatusCode(), is(OK));
90-
assertThat(entity.getBody(), is("bonjour le monde"));
86+
assertThat(entity.getBody(), is("hello world, bonjour le monde"));
9187

9288
TimeUnit.MILLISECONDS.sleep(1000);
9389

94-
List<String> tracingMessages = appender.pollLogs(".*\\[\\w+/\\w+\\]\\s+INFO.*in /.*");
95-
for (int i = 0; i < tracingMessages.size(); i+=2) {
96-
// caller is the root of tracing tree and its traceId is the same as spanId
97-
String[] ids = tracingIds(tracingMessages.get(i));
98-
String parentTraceId = ids[0];
99-
String parentSpanId = ids[1];
90+
Collection<String> tracingMessages = appender.pollLogs(".*\\[\\w+/\\w+/\\w*\\]\\s+INFO.*in /.*");
91+
assertThat(tracingMessages.isEmpty(), is(false));
10092

101-
assertThat(parentTraceId, is(parentSpanId));
93+
Iterator<String> iterator = tracingMessages.iterator();
94+
// caller is the root of tracing tree and its traceId is the same as spanId
95+
String[] ids = tracingIds(iterator.next());
96+
String parentTraceId = ids[0];
97+
String parentSpanId = ids[1];
10298

99+
assertThat(parentTraceId, is(parentSpanId));
100+
while (iterator.hasNext()) {
101+
String message = iterator.next();
103102
// callee is called by caller and inherits caller's traceId but has its own spanId
104-
ids = tracingIds(tracingMessages.get(i + 1));
103+
ids = tracingIds(message);
105104
String childTraceId = ids[0];
106105
String childSpanId = ids[1];
106+
String childParentId = ids[2];
107107

108108
assertThat(childTraceId, is(parentTraceId));
109109
assertThat(childSpanId, is(not(parentTraceId)));
110+
assertThat(childParentId, is(parentSpanId));
111+
112+
parentSpanId = childSpanId;
110113
}
111114

112115
poller.assertEventually(() -> {
113116
try {
114-
verify(exactly(2), postRequestedFor(urlEqualTo("/api/v1/spans")));
117+
verify(exactly(1), postRequestedFor(urlEqualTo("/api/v1/spans")));
115118
return true;
116119
} catch (Exception e) {
117120
return false;
@@ -121,6 +124,6 @@ public void sendsTracingToConfiguredAddress() throws InterruptedException {
121124
}
122125

123126
private String[] tracingIds(String message) {
124-
return message.replaceFirst(".*\\[(\\w+/\\w+)\\].*", "$1").trim().split("/");
127+
return message.replaceFirst(".*\\[(\\w+/\\w+/\\w*)\\].*", "$1").trim().split("/");
125128
}
126129
}

0 commit comments

Comments
 (0)