Merge pull request #120 from spring-cloud/issues_#98_match_opentracing_span
[Match OpenTracing] Matching Tracer
This commit is contained in:
12
build-tools/pom.xml
Normal file
12
build-tools/pom.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>build-tools</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<name>build-tools</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Spring Cloud Sleuth Build Tools</description>
|
||||
</project>
|
||||
202
build-tools/src/main/resources/LICENSE.txt
Normal file
202
build-tools/src/main/resources/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
18
build-tools/src/main/resources/checkstyle.xml
Normal file
18
build-tools/src/main/resources/checkstyle.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<!-- this. in front of fields -->
|
||||
<module name="RequireThis">
|
||||
<property name="checkMethods" value="false"/>
|
||||
</module>
|
||||
<module name="TreeWalker">
|
||||
<!-- tabs instead of spaces -->
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="^\t* "/>
|
||||
<property name="message" value="Indent must use tab characters"/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
||||
43
pom.xml
43
pom.xml
@@ -26,6 +26,7 @@
|
||||
</scm>
|
||||
|
||||
<modules>
|
||||
<module>build-tools</module>
|
||||
<module>spring-cloud-sleuth-dependencies</module>
|
||||
<module>spring-cloud-sleuth-core</module>
|
||||
<module>spring-cloud-sleuth-zipkin</module>
|
||||
@@ -91,8 +92,49 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>${checkstyle.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>build-tools</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>verify-style</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<logViolationsToConsole>true</logViolationsToConsole>
|
||||
<failOnViolation>false</failOnViolation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>${checkstyle.version}</version>
|
||||
<configuration>
|
||||
<configLocation>checkstyle.xml</configLocation>
|
||||
<headerLocation>LICENSE.txt</headerLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -164,6 +206,7 @@
|
||||
<maven.compiler.testTarget>1.8</maven.compiler.testTarget>
|
||||
<maven.compiler.testSource>1.8</maven.compiler.testSource>
|
||||
<surefire.plugin.version>2.19.1</surefire.plugin.version>
|
||||
<checkstyle.version>2.17</checkstyle.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Singular;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@Builder(toBuilder=true)
|
||||
public class MilliSpan implements Span {
|
||||
private final long begin;
|
||||
private long end = 0;
|
||||
private final String name;
|
||||
private final long traceId;
|
||||
@Singular
|
||||
private List<Long> parents = new ArrayList<>();
|
||||
private final long spanId;
|
||||
private boolean remote = false;
|
||||
private boolean exportable = true;
|
||||
private final Map<String, String> tags = new LinkedHashMap<>();
|
||||
private final String processId;
|
||||
@Singular
|
||||
private final List<Log> logs = new ArrayList<>();
|
||||
|
||||
public static MilliSpan.MilliSpanBuilder builder() {
|
||||
return new MilliSpan().toBuilder();
|
||||
}
|
||||
|
||||
public MilliSpan(long begin, long end, String name, long traceId, List<Long> parents, long spanId, boolean remote, boolean exportable, String processId) {
|
||||
this.begin = begin<=0 ? System.currentTimeMillis() : begin;
|
||||
this.end = end;
|
||||
this.name = name;
|
||||
this.traceId = traceId;
|
||||
this.parents = parents;
|
||||
this.spanId = spanId;
|
||||
this.remote = remote;
|
||||
this.exportable = exportable;
|
||||
this.processId = processId;
|
||||
}
|
||||
|
||||
//for serialization
|
||||
private MilliSpan() {
|
||||
this.begin = 0;
|
||||
this.name = null;
|
||||
this.traceId = 0;
|
||||
this.spanId = 0;
|
||||
this.processId = null;
|
||||
this.parents = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void stop() {
|
||||
if (this.end == 0) {
|
||||
if (this.begin == 0) {
|
||||
throw new IllegalStateException("Span for " + this.name
|
||||
+ " has not been started");
|
||||
}
|
||||
this.end = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getAccumulatedMillis() {
|
||||
if (this.begin == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (this.end > 0) {
|
||||
return this.end - this.begin;
|
||||
}
|
||||
return System.currentTimeMillis() - this.begin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isRunning() {
|
||||
return this.begin != 0 && this.end == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tag(String key, String value) {
|
||||
this.tags.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String msg) {
|
||||
this.logs.add(new Log(System.currentTimeMillis(),
|
||||
msg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> tags() {
|
||||
return Collections.unmodifiableMap(this.tags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Log> logs() {
|
||||
return Collections.unmodifiableList(this.logs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,32 +18,7 @@ package org.springframework.cloud.sleuth;
|
||||
|
||||
/**
|
||||
* Extremely simple callback to determine the frequency that an action should be
|
||||
* performed.
|
||||
* <p/>
|
||||
* 'T' is the object type you require to create a more advanced sampling
|
||||
* function. For example if there is some RPC information in a 'Call' object,
|
||||
* you might implement Sampler<Call>. Then when the RPC is received you can call
|
||||
* one of the Trace.java functions that takes the extra 'info' parameter, which
|
||||
* will be passed into the next function you implemented.
|
||||
* <p/>
|
||||
* For the example above, the next(T info) function may look like this
|
||||
* <p/>
|
||||
* <pre>
|
||||
* <code>public boolean next(T info) {
|
||||
* if (info == null) {
|
||||
* return false;
|
||||
* } else if (info.getName().equals("get")) {
|
||||
* return Math.random() > 0.5;
|
||||
* } else if (info.getName().equals("put")) {
|
||||
* return Math.random() > 0.25;
|
||||
* } else {
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* This would trace 50% of all gets, 75% of all puts and would not trace any other requests.
|
||||
*/
|
||||
public interface Sampler<T> {
|
||||
public interface Sampler {
|
||||
boolean next();
|
||||
}
|
||||
|
||||
@@ -16,104 +16,161 @@
|
||||
|
||||
package org.springframework.cloud.sleuth;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Singular;
|
||||
import lombok.ToString;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface for gathering and reporting statistics about a block of execution.
|
||||
* Class for gathering and reporting statistics about a block of execution.
|
||||
* <p/>
|
||||
* Spans should form a directed acyclic graph structure. It should be possible to keep
|
||||
* following the parents of a span until you arrive at a span with no parents.
|
||||
* <p/>
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public interface Span {
|
||||
@Builder(toBuilder = true)
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@Getter
|
||||
public class Span {
|
||||
|
||||
/**
|
||||
* A human-readable name assigned to this span instance.
|
||||
* <p/>
|
||||
*/
|
||||
String getName();
|
||||
public static final String NOT_SAMPLED_NAME = "X-Not-Sampled";
|
||||
public static final String PROCESS_ID_NAME = "X-Process-Id";
|
||||
public static final String PARENT_ID_NAME = "X-Parent-Id";
|
||||
public static final String TRACE_ID_NAME = "X-Trace-Id";
|
||||
public static final String SPAN_NAME_NAME = "X-Span-Name";
|
||||
public static final String SPAN_ID_NAME = "X-Span-Id";
|
||||
public static final List<String> HEADERS = Arrays
|
||||
.asList(SPAN_ID_NAME, TRACE_ID_NAME, SPAN_NAME_NAME, PARENT_ID_NAME,
|
||||
PROCESS_ID_NAME, NOT_SAMPLED_NAME);
|
||||
public static final String SPAN_EXPORT_NAME = "X-Span-Export";
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to this span instance.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* The spanId is immutable and cannot be changed. It is safe to access this from
|
||||
* multiple threads.
|
||||
*/
|
||||
long getSpanId();
|
||||
private final long begin;
|
||||
private long end = 0;
|
||||
private final String name;
|
||||
private final long traceId;
|
||||
@Singular
|
||||
private List<Long> parents = new ArrayList<>();
|
||||
private final long spanId;
|
||||
private boolean remote = false;
|
||||
private boolean exportable = true;
|
||||
private final Map<String, String> tags = new LinkedHashMap<>();
|
||||
private final String processId;
|
||||
@Singular
|
||||
private final List<Log> logs = new ArrayList<>();
|
||||
private final Span savedSpan;
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to the trace associated with this span
|
||||
*/
|
||||
long getTraceId();
|
||||
public static Span.SpanBuilder builder() {
|
||||
return new Span().toBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique id for the process from which this Span originated.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* // TODO: Check when this is going to be null (cause it may be null)
|
||||
*/
|
||||
String getProcessId();
|
||||
public Span(Span current, Span savedSpan) {
|
||||
this.begin = current.getBegin();
|
||||
this.end = current.getEnd();
|
||||
this.name = current.getName();
|
||||
this.traceId = current.getTraceId();
|
||||
this.parents = current.getParents();
|
||||
this.spanId = current.getSpanId();
|
||||
this.remote = current.isRemote();
|
||||
this.exportable = current.isExportable();
|
||||
this.processId = current.getProcessId();
|
||||
this.tags.putAll(current.tags());
|
||||
this.logs.addAll(current.logs());
|
||||
this.savedSpan = savedSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent IDs of the span.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* The collection will be empty if there are no parents.
|
||||
*/
|
||||
List<Long> getParents();
|
||||
public Span(long begin, long end, String name, long traceId, List<Long> parents,
|
||||
long spanId, boolean remote, boolean exportable, String processId) {
|
||||
this(begin, end, name, traceId, parents, spanId, remote, exportable, processId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag that tells us whether the span was started in another process. Useful in RPC
|
||||
* tracing when the receiver actually has to add annotations to the senders span.
|
||||
*/
|
||||
boolean isRemote();
|
||||
public Span(long begin, long end, String name, long traceId, List<Long> parents,
|
||||
long spanId, boolean remote, boolean exportable, String processId,
|
||||
Span savedSpan) {
|
||||
this.begin = begin<=0 ? System.currentTimeMillis() : begin;
|
||||
this.end = end;
|
||||
this.name = name;
|
||||
this.traceId = traceId;
|
||||
this.parents = parents;
|
||||
this.spanId = spanId;
|
||||
this.remote = remote;
|
||||
this.exportable = exportable;
|
||||
this.processId = processId;
|
||||
this.savedSpan = savedSpan;
|
||||
}
|
||||
|
||||
//for serialization
|
||||
private Span() {
|
||||
this.begin = 0;
|
||||
this.name = null;
|
||||
this.traceId = 0;
|
||||
this.spanId = 0;
|
||||
this.processId = null;
|
||||
this.parents = new ArrayList<>();
|
||||
this.savedSpan = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The block has completed, stop the clock
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Get the start time, in milliseconds
|
||||
*/
|
||||
long getBegin();
|
||||
|
||||
/**
|
||||
* Get the stop time, in milliseconds
|
||||
*/
|
||||
long getEnd();
|
||||
public synchronized void stop() {
|
||||
if (this.end == 0) {
|
||||
if (this.begin == 0) {
|
||||
throw new IllegalStateException("Span for " + this.name
|
||||
+ " has not been started");
|
||||
}
|
||||
this.end = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total amount of time elapsed since start was called, if running, or
|
||||
* difference between stop and start
|
||||
*/
|
||||
long getAccumulatedMillis();
|
||||
public synchronized long getAccumulatedMillis() {
|
||||
if (this.begin == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (this.end > 0) {
|
||||
return this.end - this.begin;
|
||||
}
|
||||
return System.currentTimeMillis() - this.begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the span been started and not yet stopped?
|
||||
*/
|
||||
boolean isRunning();
|
||||
|
||||
/**
|
||||
* Is the span eligible for export? If not then we may not need accumulate annotations
|
||||
* (for instance).
|
||||
*/
|
||||
boolean isExportable();
|
||||
public synchronized boolean isRunning() {
|
||||
return this.begin != 0 && this.end == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tag or data annotation associated with this span
|
||||
*/
|
||||
void tag(String key, String value);
|
||||
public void tag(String key, String value) {
|
||||
this.tags.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log or timeline annotation associated with this span
|
||||
*/
|
||||
void log(String msg);
|
||||
public void log(String msg) {
|
||||
this.logs.add(new Log(System.currentTimeMillis(),
|
||||
msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tag data associated with this span (read only)
|
||||
@@ -121,7 +178,9 @@ public interface Span {
|
||||
* <p/>
|
||||
* Will never be null.
|
||||
*/
|
||||
Map<String, String> tags();
|
||||
public Map<String, String> tags() {
|
||||
return Collections.unmodifiableMap(this.tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any logs or annotations (read only)
|
||||
@@ -129,27 +188,111 @@ public interface Span {
|
||||
* <p/>
|
||||
* Will never be null.
|
||||
*/
|
||||
List<Log> logs();
|
||||
|
||||
public List<Log> logs() {
|
||||
return Collections.unmodifiableList(this.logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used for conversions of long ids to their String representation
|
||||
* Returns the saved span. The one that was "current" before this Span.
|
||||
* <p>
|
||||
* Might be null
|
||||
*/
|
||||
class IdConverter {
|
||||
public Span getSavedSpan() {
|
||||
return this.savedSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents given long id as hex string
|
||||
*/
|
||||
public static String toHex(long id) {
|
||||
return Long.toHexString(id);
|
||||
}
|
||||
public boolean hasSavedSpan() {
|
||||
return this.savedSpan != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents hex string as long
|
||||
*/
|
||||
public static long fromHex(String hexString) {
|
||||
Assert.hasText(hexString, "Can't convert empty hex string to long");
|
||||
return new BigInteger(hexString, 16).longValue();
|
||||
}
|
||||
/**
|
||||
* A human-readable name assigned to this span instance.
|
||||
* <p>
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to this span instance.
|
||||
* <p>
|
||||
* <p>
|
||||
* The spanId is immutable and cannot be changed. It is safe to access this from
|
||||
* multiple threads.
|
||||
*/
|
||||
public long getSpanId() {
|
||||
return this.spanId;
|
||||
}
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to the trace associated with this span
|
||||
*/
|
||||
public long getTraceId() {
|
||||
return this.traceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique id for the process from which this Span originated.
|
||||
* <p>
|
||||
* <p>
|
||||
* // TODO: Check when this is going to be null (cause it may be null)
|
||||
*/
|
||||
public String getProcessId() {
|
||||
return this.processId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent IDs of the span.
|
||||
* <p>
|
||||
* <p>
|
||||
* The collection will be empty if there are no parents.
|
||||
*/
|
||||
public List<Long> getParents() {
|
||||
return this.parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag that tells us whether the span was started in another process. Useful in RPC
|
||||
* tracing when the receiver actually has to add annotations to the senders span.
|
||||
*/
|
||||
public boolean isRemote() {
|
||||
return this.remote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start time, in milliseconds
|
||||
*/
|
||||
public long getBegin() {
|
||||
return this.begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stop time, in milliseconds
|
||||
*/
|
||||
public long getEnd() {
|
||||
return this.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the span eligible for export? If not then we may not need accumulate annotations
|
||||
* (for instance).
|
||||
*/
|
||||
public boolean isExportable() {
|
||||
return this.exportable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents given long id as hex string
|
||||
*/
|
||||
public static String toHex(long id) {
|
||||
return Long.toHexString(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents hex string as long
|
||||
*/
|
||||
public static long fromHex(String hexString) {
|
||||
Assert.hasText(hexString, "Can't convert empty hex string to long");
|
||||
return new BigInteger(hexString, 16).longValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
||||
/**
|
||||
* A wrapper around the current span with context for a possible hierarchy or stack of
|
||||
* spans being monitored.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Value
|
||||
@NonFinal
|
||||
public class Trace {
|
||||
|
||||
public static final String NOT_SAMPLED_NAME = "X-Not-Sampled";
|
||||
|
||||
public static final String PROCESS_ID_NAME = "X-Process-Id";
|
||||
|
||||
public static final String PARENT_ID_NAME = "X-Parent-Id";
|
||||
|
||||
public static final String TRACE_ID_NAME = "X-Trace-Id";
|
||||
|
||||
public static final String SPAN_NAME_NAME = "X-Span-Name";
|
||||
|
||||
public static final String SPAN_ID_NAME = "X-Span-Id";
|
||||
|
||||
public static final String SPAN_EXPORT_NAME = "X-Span-Export";
|
||||
|
||||
public static final List<String> HEADERS = Arrays.asList(SPAN_ID_NAME, TRACE_ID_NAME,
|
||||
SPAN_NAME_NAME, PARENT_ID_NAME, PROCESS_ID_NAME, NOT_SAMPLED_NAME);
|
||||
|
||||
/**
|
||||
* the span for this trace
|
||||
*/
|
||||
private final Span span;
|
||||
|
||||
/**
|
||||
* the trace that was "current" before this trace was entered
|
||||
*/
|
||||
private final Trace saved;
|
||||
|
||||
public Trace(Trace saved, Span span) {
|
||||
this.saved = saved;
|
||||
this.span = span;
|
||||
}
|
||||
|
||||
public Trace(Span span) {
|
||||
this(null, span);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,14 +31,8 @@ import java.util.concurrent.Callable;
|
||||
* With care, it is possible to safely pass a Span object between threads, but in most
|
||||
* cases this is not necessary.
|
||||
*
|
||||
* A 'TraceScope' can either be empty, or contain a Span. TraceScope objects implement the
|
||||
* Java's Closeable interface. Similar to file descriptors, they must be closed after they
|
||||
* are created. When a TraceScope contains a Span, this span is closed when the scope is
|
||||
* closed.
|
||||
* The 'startTrace' method in this class starts a new span.
|
||||
*
|
||||
* The 'startTrace' methods in this class do a few things:
|
||||
* <ul>
|
||||
* <li>Set currentSpan to the new Span.</li>
|
||||
* <li>Create a TraceSpan object to manage the new Span.</li>
|
||||
* </ul>
|
||||
*
|
||||
@@ -53,18 +47,18 @@ import java.util.concurrent.Callable;
|
||||
public interface Tracer extends TraceAccessor {
|
||||
|
||||
/**
|
||||
* Creates a trace wrapping a new span.
|
||||
* Creates a new Span.
|
||||
* <p/>
|
||||
* If this thread has a currently active span, it will be the parent of the span we
|
||||
* create here, and the trace scope will contain the new span and the parent. If there
|
||||
* is no currently active trace span, the trace scope we create will be empty.
|
||||
* create here. If there is no currently active trace span, the trace scope we
|
||||
* create will be empty.
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
Trace startTrace(String name);
|
||||
Span startTrace(String name);
|
||||
|
||||
/**
|
||||
* Creates a new trace scope with a specific parent. The parent might be in another
|
||||
* Creates a new Span with a specific parent. The parent might be in another
|
||||
* process or thread.
|
||||
* <p/>
|
||||
* If this thread has a currently active trace span, it must be the 'parent' span that
|
||||
@@ -73,7 +67,7 @@ public interface Tracer extends TraceAccessor {
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
Trace joinTrace(String name, Span parent);
|
||||
Span joinTrace(String name, Span parent);
|
||||
|
||||
/**
|
||||
* Start a new span if the sampler allows it or if we are already tracing in this
|
||||
@@ -81,12 +75,12 @@ public interface Tracer extends TraceAccessor {
|
||||
* @param name the name of the span
|
||||
* @param sampler a sampler to decide whether to create the span or not
|
||||
*/
|
||||
<T> Trace startTrace(String name, Sampler<T> sampler);
|
||||
Span startTrace(String name, Sampler sampler);
|
||||
|
||||
/**
|
||||
* Pick up an existing span from another thread.
|
||||
*/
|
||||
Trace continueSpan(Span s);
|
||||
Span continueSpan(Span span);
|
||||
|
||||
/**
|
||||
* Adds a tag to the current span if tracing is currently on.
|
||||
@@ -96,19 +90,19 @@ public interface Tracer extends TraceAccessor {
|
||||
/**
|
||||
* Remove this span from the current thread, but don't stop it yet or send it for
|
||||
* collection. This is useful if the span object is then passed to another thread for
|
||||
* use with Trace.continueTrace().
|
||||
* use with Span.continueTrace().
|
||||
*
|
||||
* @return the saved trace if there was one before the trace started (null otherwise)
|
||||
*/
|
||||
Trace detach(Trace trace);
|
||||
Span detach(Span span);
|
||||
|
||||
/**
|
||||
* Remove this span from the current thread, stop it and send it for collection.
|
||||
*
|
||||
* @param trace the trace to close
|
||||
* @return the saved trace if there was one before the trace started (null otherwise)
|
||||
* @param span the span to close
|
||||
* @return the saved span if there was one before the trace started (null otherwise)
|
||||
*/
|
||||
Trace close(Trace trace);
|
||||
Span close(Span span);
|
||||
|
||||
<V> Callable<V> wrap(Callable<V> callable);
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@ public class TraceAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Sampler<Void> defaultTraceSampler() {
|
||||
public Sampler defaultTraceSampler() {
|
||||
return new IsTracingSampler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public DefaultTracer traceManager(Sampler<Void> sampler,
|
||||
public DefaultTracer traceManager(Sampler sampler,
|
||||
ApplicationEventPublisher publisher) {
|
||||
return new DefaultTracer(sampler, random(), publisher);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
@@ -35,9 +35,9 @@ import org.springframework.util.ClassUtils;
|
||||
public class TraceBootstrapEnvironmentPostProcessor implements EnvironmentPostProcessor {
|
||||
|
||||
private static final String PROPERTY_SOURCE_NAME = "defaultProperties";
|
||||
private static String[] headers = new String[] { Trace.SPAN_ID_NAME,
|
||||
Trace.TRACE_ID_NAME, Trace.PARENT_ID_NAME, Trace.PROCESS_ID_NAME,
|
||||
Trace.NOT_SAMPLED_NAME, Trace.SPAN_NAME_NAME };
|
||||
private static String[] headers = new String[] { Span.SPAN_ID_NAME,
|
||||
Span.TRACE_ID_NAME, Span.PARENT_ID_NAME, Span.PROCESS_ID_NAME,
|
||||
Span.NOT_SAMPLED_NAME, Span.SPAN_NAME_NAME };
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -43,12 +43,12 @@ public class TraceCallable<V> extends TraceDelegate<Callable<V>> implements Call
|
||||
@Override
|
||||
public V call() throws Exception {
|
||||
ensureThatThreadIsNotPollutedByPreviousTraces();
|
||||
Trace trace = startSpan();
|
||||
Span span = startSpan();
|
||||
try {
|
||||
return this.getDelegate().call();
|
||||
}
|
||||
finally {
|
||||
closeAll(trace);
|
||||
closeAll(span);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -45,18 +43,18 @@ public abstract class TraceDelegate<T> {
|
||||
this.parent = tracer.getCurrentSpan();
|
||||
}
|
||||
|
||||
protected void close(Trace trace) {
|
||||
this.tracer.close(trace);
|
||||
protected void close(Span span) {
|
||||
this.tracer.close(span);
|
||||
}
|
||||
|
||||
protected void closeAll(Trace trace) {
|
||||
trace = this.tracer.close(trace);
|
||||
while (trace != null) {
|
||||
trace = this.tracer.detach(trace);
|
||||
protected void closeAll(Span span) {
|
||||
span = this.tracer.close(span);
|
||||
while (span != null) {
|
||||
span = this.tracer.detach(span);
|
||||
}
|
||||
}
|
||||
|
||||
protected Trace startSpan() {
|
||||
protected Span startSpan() {
|
||||
return this.tracer.joinTrace(getSpanName(), this.parent);
|
||||
}
|
||||
|
||||
@@ -65,6 +63,6 @@ public abstract class TraceDelegate<T> {
|
||||
}
|
||||
|
||||
protected void ensureThatThreadIsNotPollutedByPreviousTraces() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -40,12 +40,12 @@ public class TraceRunnable extends TraceDelegate<Runnable> implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
ensureThatThreadIsNotPollutedByPreviousTraces();
|
||||
Trace trace = startSpan();
|
||||
Span span = startSpan();
|
||||
try {
|
||||
this.getDelegate().run();
|
||||
}
|
||||
finally {
|
||||
closeAll(trace);
|
||||
closeAll(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,8 @@ import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixThreadPoolKey;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
|
||||
/**
|
||||
* Abstraction over {@code HystrixCommand} that wraps command execution with Trace setting
|
||||
@@ -72,17 +71,17 @@ public abstract class TraceCommand<R> extends HystrixCommand<R> {
|
||||
@Override
|
||||
protected R run() throws Exception {
|
||||
enforceThatHystrixThreadIsNotPollutedByPreviousTraces();
|
||||
Trace trace = this.tracer.joinTrace(getCommandKey().name(), parentSpan);
|
||||
Span span = this.tracer.joinTrace(getCommandKey().name(), parentSpan);
|
||||
try {
|
||||
return doRun();
|
||||
} finally {
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Do more analysis why this is not removed properly
|
||||
private void enforceThatHystrixThreadIsNotPollutedByPreviousTraces() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
public abstract R doRun() throws Exception;
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
@@ -13,6 +9,8 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.ChannelInterceptorAdapter;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Abstraction over classes related to channel intercepting
|
||||
*
|
||||
@@ -45,19 +43,19 @@ abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter
|
||||
* trace id passed initially.
|
||||
*/
|
||||
Span buildSpan(Message<?> message) {
|
||||
if (!hasHeader(message, Trace.TRACE_ID_NAME) || !hasHeader(message, Trace.SPAN_ID_NAME)) {
|
||||
if (!hasHeader(message, Span.TRACE_ID_NAME) || !hasHeader(message, Span.SPAN_ID_NAME)) {
|
||||
return null; // cannot build a span without ids
|
||||
}
|
||||
long spanId = hasHeader(message, Trace.SPAN_ID_NAME) ?
|
||||
getHeader(message, Trace.SPAN_ID_NAME, Long.class) : this.random.nextLong();
|
||||
long traceId = getHeader(message, Trace.TRACE_ID_NAME, Long.class);
|
||||
MilliSpan.MilliSpanBuilder span = MilliSpan.builder().traceId(traceId).spanId(spanId);
|
||||
Long parentId = getHeader(message, Trace.PARENT_ID_NAME, Long.class);
|
||||
if (message.getHeaders().containsKey(Trace.NOT_SAMPLED_NAME)) {
|
||||
long spanId = hasHeader(message, Span.SPAN_ID_NAME) ?
|
||||
getHeader(message, Span.SPAN_ID_NAME, Long.class) : this.random.nextLong();
|
||||
long traceId = getHeader(message, Span.TRACE_ID_NAME, Long.class);
|
||||
Span.SpanBuilder span = Span.builder().traceId(traceId).spanId(spanId);
|
||||
Long parentId = getHeader(message, Span.PARENT_ID_NAME, Long.class);
|
||||
if (message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
|
||||
span.exportable(false);
|
||||
}
|
||||
String processId = getHeader(message, Trace.PROCESS_ID_NAME);
|
||||
String spanName = getHeader(message, Trace.SPAN_NAME_NAME);
|
||||
String processId = getHeader(message, Span.PROCESS_ID_NAME);
|
||||
String spanName = getHeader(message, Span.SPAN_NAME_NAME);
|
||||
if (spanName != null) {
|
||||
span.name(spanName);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,16 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility for manipulating message headers related to span data.
|
||||
*
|
||||
@@ -38,25 +37,25 @@ public class SpanMessageHeaders {
|
||||
public static Message<?> addSpanHeaders(TraceKeys traceKeys, Message<?> message,
|
||||
Span span) {
|
||||
if (span == null) {
|
||||
if (!message.getHeaders().containsKey(Trace.NOT_SAMPLED_NAME)) {
|
||||
if (!message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
|
||||
return MessageBuilder.fromMessage(message)
|
||||
.setHeader(Trace.NOT_SAMPLED_NAME, "").build();
|
||||
.setHeader(Span.NOT_SAMPLED_NAME, "").build();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
addHeader(headers, Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
addHeader(headers, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
addHeader(headers, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
addHeader(headers, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
|
||||
if (span.isExportable()) {
|
||||
addAnnotations(traceKeys, message, span);
|
||||
addHeader(headers, Trace.PARENT_ID_NAME, getFirst(span.getParents()));
|
||||
addHeader(headers, Trace.SPAN_NAME_NAME, span.getName());
|
||||
addHeader(headers, Trace.PROCESS_ID_NAME, span.getProcessId());
|
||||
addHeader(headers, Span.PARENT_ID_NAME, getFirst(span.getParents()));
|
||||
addHeader(headers, Span.SPAN_NAME_NAME, span.getName());
|
||||
addHeader(headers, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
}
|
||||
else {
|
||||
addHeader(headers, Trace.NOT_SAMPLED_NAME, "");
|
||||
addHeader(headers, Span.NOT_SAMPLED_NAME, "");
|
||||
}
|
||||
return MessageBuilder.fromMessage(message).copyHeaders(headers).build();
|
||||
}
|
||||
@@ -100,7 +99,7 @@ public class SpanMessageHeaders {
|
||||
|
||||
private static void addHeader(Map<String, String> headers, String name, Long value) {
|
||||
if (value != null) {
|
||||
addHeader(headers, name, Span.IdConverter.toHex(value));
|
||||
addHeader(headers, name, Span.toHex(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,17 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Builder class to create STOMP message
|
||||
*
|
||||
@@ -62,16 +61,16 @@ public class StompMessageBuilder {
|
||||
|
||||
public StompMessageBuilder setHeadersFromSpan(final Span span) {
|
||||
if (span != null) {
|
||||
setHeaderIfAbsent(Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeaderIfAbsent(Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeaderIfAbsent(Trace.SPAN_NAME_NAME, span.getName());
|
||||
Long parentId = getParentId(TraceContextHolder.getCurrentSpan());
|
||||
setHeaderIfAbsent(Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeaderIfAbsent(Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeaderIfAbsent(Span.SPAN_NAME_NAME, span.getName());
|
||||
Long parentId = getParentId(SpanContextHolder.getCurrentSpan());
|
||||
if (parentId != null)
|
||||
setHeaderIfAbsent(Trace.PARENT_ID_NAME, parentId);
|
||||
setHeaderIfAbsent(Span.PARENT_ID_NAME, parentId);
|
||||
|
||||
String processId = span.getProcessId();
|
||||
if (StringUtils.hasText(processId))
|
||||
setHeaderIfAbsent(Trace.PROCESS_ID_NAME, processId);
|
||||
setHeaderIfAbsent(Span.PROCESS_ID_NAME, processId);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -101,12 +100,12 @@ public class StompMessageBuilder {
|
||||
case SimpMessageHeaderAccessor.HEART_BEAT_HEADER:
|
||||
case SimpMessageHeaderAccessor.ORIGINAL_DESTINATION:
|
||||
case SimpMessageHeaderAccessor.IGNORE_ERROR:
|
||||
case Trace.NOT_SAMPLED_NAME:
|
||||
case Trace.PARENT_ID_NAME:
|
||||
case Trace.PROCESS_ID_NAME:
|
||||
case Trace.SPAN_ID_NAME:
|
||||
case Trace.SPAN_NAME_NAME:
|
||||
case Trace.TRACE_ID_NAME:
|
||||
case Span.NOT_SAMPLED_NAME:
|
||||
case Span.PARENT_ID_NAME:
|
||||
case Span.PROCESS_ID_NAME:
|
||||
case Span.SPAN_ID_NAME:
|
||||
case Span.SPAN_NAME_NAME:
|
||||
case Span.TRACE_ID_NAME:
|
||||
accessor.setHeader(key, value);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -16,23 +16,22 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor {
|
||||
|
||||
private ThreadLocal<Trace> traceHolder = new ThreadLocal<>();
|
||||
private ThreadLocal<Span> traceHolder = new ThreadLocal<>();
|
||||
|
||||
public TraceChannelInterceptor(Tracer tracer, TraceKeys traceKeys, Random random) {
|
||||
super(tracer, traceKeys, random);
|
||||
@@ -40,7 +39,7 @@ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor {
|
||||
|
||||
@Override
|
||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||
Trace trace = this.traceHolder.get();
|
||||
Span trace = this.traceHolder.get();
|
||||
// Double close to clean up the parent (remote span as well)
|
||||
getTracer().close(getTracer().close(trace));
|
||||
this.traceHolder.remove();
|
||||
@@ -53,16 +52,16 @@ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor {
|
||||
getTracer().getCurrentSpan());
|
||||
}
|
||||
String name = getMessageChannelName(channel);
|
||||
Trace trace = startSpan(buildSpan(message), name, message);
|
||||
this.traceHolder.set(trace);
|
||||
return SpanMessageHeaders.addSpanHeaders(getTraceKeys(), message, trace.getSpan());
|
||||
Span span = startSpan(buildSpan(message), name, message);
|
||||
this.traceHolder.set(span);
|
||||
return SpanMessageHeaders.addSpanHeaders(getTraceKeys(), message, span);
|
||||
}
|
||||
|
||||
private Trace startSpan(Span span, String name, Message<?> message) {
|
||||
private Span startSpan(Span span, String name, Message<?> message) {
|
||||
if (span != null) {
|
||||
return getTracer().joinTrace(name, span);
|
||||
}
|
||||
if (message.getHeaders().containsKey(Trace.NOT_SAMPLED_NAME)) {
|
||||
if (message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
|
||||
return getTracer().startTrace(name, IsTracingSampler.INSTANCE);
|
||||
}
|
||||
return getTracer().startTrace(name);
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -50,7 +49,7 @@ public class TraceContextPropagationChannelInterceptor extends ChannelIntercepto
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
private final static ThreadLocal<Trace> ORIGINAL_CONTEXT = new ThreadLocal<>();
|
||||
private final static ThreadLocal<Span> ORIGINAL_CONTEXT = new ThreadLocal<>();
|
||||
|
||||
public TraceContextPropagationChannelInterceptor(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
@@ -101,12 +100,12 @@ public class TraceContextPropagationChannelInterceptor extends ChannelIntercepto
|
||||
protected void populatePropagatedContext(Span span, Message<?> message,
|
||||
MessageChannel channel) {
|
||||
if (span != null) {
|
||||
ORIGINAL_CONTEXT.set(this.tracer.continueSpan(span).getSaved());
|
||||
ORIGINAL_CONTEXT.set(this.tracer.continueSpan(span).getSavedSpan());
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetPropagatedContext() {
|
||||
Trace originalContext = ORIGINAL_CONTEXT.get();
|
||||
Span originalContext = ORIGINAL_CONTEXT.get();
|
||||
this.tracer.detach(originalContext);
|
||||
ORIGINAL_CONTEXT.remove();
|
||||
}
|
||||
@@ -128,16 +127,16 @@ public class TraceContextPropagationChannelInterceptor extends ChannelIntercepto
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.putAll(message.getHeaders());
|
||||
|
||||
setHeader(headers, Trace.SPAN_ID_NAME, this.span.getSpanId());
|
||||
setHeader(headers, Trace.TRACE_ID_NAME, this.span.getTraceId());
|
||||
setHeader(headers, Trace.SPAN_NAME_NAME, this.span.getName());
|
||||
setHeader(headers, Span.SPAN_ID_NAME, this.span.getSpanId());
|
||||
setHeader(headers, Span.TRACE_ID_NAME, this.span.getTraceId());
|
||||
setHeader(headers, Span.SPAN_NAME_NAME, this.span.getName());
|
||||
Long parentId = getParentId(span);
|
||||
if (parentId != null) {
|
||||
setHeader(headers, Trace.PARENT_ID_NAME, parentId);
|
||||
setHeader(headers, Span.PARENT_ID_NAME, parentId);
|
||||
}
|
||||
String processId = span.getProcessId();
|
||||
if (StringUtils.hasText(processId)) {
|
||||
setHeader(headers, Trace.PROCESS_ID_NAME, processId);
|
||||
setHeader(headers, Span.PROCESS_ID_NAME, processId);
|
||||
}
|
||||
this.messageHeaders = new MessageHeaders(headers);
|
||||
}
|
||||
@@ -148,7 +147,7 @@ public class TraceContextPropagationChannelInterceptor extends ChannelIntercepto
|
||||
}
|
||||
}
|
||||
public void setHeader(Map<String, Object> headers, String name, long value) {
|
||||
setHeader(headers, name, Span.IdConverter.toHex(value));
|
||||
setHeader(headers, name, Span.toHex(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,16 +15,15 @@
|
||||
*/
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Interceptor for Stomp Messages sent over websocket
|
||||
*
|
||||
@@ -33,7 +32,7 @@ import org.springframework.messaging.support.ChannelInterceptor;
|
||||
*
|
||||
*/
|
||||
public class TraceStompMessageChannelInterceptor extends AbstractTraceChannelInterceptor implements ChannelInterceptor {
|
||||
private ThreadLocal<Trace> traceScopeHolder = new ThreadLocal<Trace>();
|
||||
private ThreadLocal<Span> traceScopeHolder = new ThreadLocal<>();
|
||||
|
||||
public TraceStompMessageChannelInterceptor(Tracer tracer, TraceKeys traceKeys, Random random) {
|
||||
super(tracer, traceKeys, random);
|
||||
@@ -41,16 +40,16 @@ public class TraceStompMessageChannelInterceptor extends AbstractTraceChannelInt
|
||||
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
if (getTracer().isTracing() || message.getHeaders().containsKey(Trace.NOT_SAMPLED_NAME)) {
|
||||
if (getTracer().isTracing() || message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
|
||||
return StompMessageBuilder.fromMessage(message).setHeadersFromSpan(getTracer().getCurrentSpan()).build();
|
||||
}
|
||||
String name = getMessageChannelName(channel);
|
||||
Trace trace = startSpan(buildSpan(message), name);
|
||||
this.traceScopeHolder.set(trace);
|
||||
return StompMessageBuilder.fromMessage(message).setHeadersFromSpan(trace.getSpan()).build();
|
||||
Span span = startSpan(buildSpan(message), name);
|
||||
this.traceScopeHolder.set(span);
|
||||
return StompMessageBuilder.fromMessage(message).setHeadersFromSpan(span).build();
|
||||
}
|
||||
|
||||
private Trace startSpan(Span span, String name) {
|
||||
private Span startSpan(Span span, String name) {
|
||||
if (span != null) {
|
||||
return getTracer().joinTrace(name, span);
|
||||
}
|
||||
@@ -59,8 +58,8 @@ public class TraceStompMessageChannelInterceptor extends AbstractTraceChannelInt
|
||||
|
||||
@Override
|
||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||
final ThreadLocal<Trace> traceScopeHolder = this.traceScopeHolder;
|
||||
Trace traceInScope = traceScopeHolder.get();
|
||||
final ThreadLocal<Span> traceScopeHolder = this.traceScopeHolder;
|
||||
Span traceInScope = traceScopeHolder.get();
|
||||
getTracer().close(traceInScope);
|
||||
traceScopeHolder.remove();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
@@ -40,7 +39,7 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
implements ExecutorChannelInterceptor {
|
||||
|
||||
private final Tracer tracer;
|
||||
private final static ThreadLocal<Trace> ORIGINAL_CONTEXT = new ThreadLocal<>();
|
||||
private final static ThreadLocal<Span> ORIGINAL_CONTEXT = new ThreadLocal<>();
|
||||
private TraceKeys traceKeys;
|
||||
|
||||
public TraceStompMessageContextPropagationChannelInterceptor(Tracer tracer, TraceKeys traceKeys) {
|
||||
@@ -94,12 +93,12 @@ public class TraceStompMessageContextPropagationChannelInterceptor extends Chann
|
||||
|
||||
protected void populatePropagatedContext(Span span) {
|
||||
if (span != null) {
|
||||
ORIGINAL_CONTEXT.set(this.tracer.continueSpan(span).getSaved());
|
||||
ORIGINAL_CONTEXT.set(this.tracer.continueSpan(span).getSavedSpan());
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetPropagatedContext() {
|
||||
Trace originalContext = ORIGINAL_CONTEXT.get();
|
||||
Span originalContext = ORIGINAL_CONTEXT.get();
|
||||
this.tracer.detach(originalContext);
|
||||
ORIGINAL_CONTEXT.remove();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.cloud.sleuth.instrument.scheduling;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
@@ -46,12 +46,12 @@ public class TraceSchedulingAspect {
|
||||
|
||||
@Around("execution (@org.springframework.scheduling.annotation.Scheduled * *.*(..))")
|
||||
public Object traceBackgroundThread(final ProceedingJoinPoint pjp) throws Throwable {
|
||||
Trace trace = this.tracer.startTrace(pjp.toShortString());
|
||||
Span span = this.tracer.startTrace(pjp.toShortString());
|
||||
try {
|
||||
return pjp.proceed();
|
||||
}
|
||||
finally {
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,30 +15,14 @@
|
||||
*/
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.MilliSpan.MilliSpanBuilder;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span.SpanBuilder;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.ServerReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.event.ServerSentEvent;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@@ -48,16 +32,29 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* Filter that takes the value of the {@link Trace#SPAN_ID_NAME} and
|
||||
* {@link Trace#TRACE_ID_NAME} header from either request or response and uses them to
|
||||
* Filter that takes the value of the {@link Span#SPAN_ID_NAME} and
|
||||
* {@link Span#TRACE_ID_NAME} header from either request or response and uses them to
|
||||
* create a new span.
|
||||
*
|
||||
* <p>In order to keep the size of spans manageable, this only add tags defined in {@link TraceKeys}.
|
||||
* If you need to add additional tags, such as headers subtype this and override
|
||||
* {@link #addRequestTags} or {@link #addResponseTags}.
|
||||
*
|
||||
* @see TraceManager
|
||||
* @see Tracer
|
||||
* @see TraceKeys
|
||||
* @see TraceWebAutoConfiguration#traceWebFilter(TraceFilter)
|
||||
*
|
||||
@@ -106,32 +103,33 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
|
||||
String uri = this.urlPathHelper.getPathWithinApplication(request);
|
||||
boolean skip = this.skipPattern.matcher(uri).matches()
|
||||
|| getHeader(request, response, Trace.NOT_SAMPLED_NAME) != null;
|
||||
|| getHeader(request, response, Span.NOT_SAMPLED_NAME) != null;
|
||||
|
||||
Trace trace = (Trace) request.getAttribute(TRACE_REQUEST_ATTR);
|
||||
if (trace != null) {
|
||||
this.tracer.continueSpan(trace.getSpan());
|
||||
Span spanFromRequest = (Span) request.getAttribute(TRACE_REQUEST_ATTR);
|
||||
if (spanFromRequest != null) {
|
||||
this.tracer.continueSpan(spanFromRequest);
|
||||
}
|
||||
else if (skip) {
|
||||
addToResponseIfNotPresent(response, Trace.NOT_SAMPLED_NAME, "");
|
||||
addToResponseIfNotPresent(response, Span.NOT_SAMPLED_NAME, "");
|
||||
}
|
||||
|
||||
String name = "http" + uri;
|
||||
if (hasHeader(request, response, Trace.TRACE_ID_NAME)) {
|
||||
long traceId = Span.IdConverter.fromHex(getHeader(request, response, Trace.TRACE_ID_NAME));
|
||||
long spanId = hasHeader(request, response, Trace.SPAN_ID_NAME) ?
|
||||
Span.IdConverter.fromHex(getHeader(request, response, Trace.SPAN_ID_NAME)) : this.random.nextLong();
|
||||
if (hasHeader(request, response, Span.TRACE_ID_NAME)) {
|
||||
long traceId = Span.fromHex(getHeader(request, response, Span.TRACE_ID_NAME));
|
||||
long spanId = hasHeader(request, response, Span.SPAN_ID_NAME) ?
|
||||
Span.fromHex(getHeader(request, response, Span.SPAN_ID_NAME)) :
|
||||
this.random.nextLong();
|
||||
|
||||
MilliSpanBuilder span = MilliSpan.builder().traceId(traceId).spanId(spanId);
|
||||
SpanBuilder span = Span.builder().traceId(traceId).spanId(spanId);
|
||||
if (skip) {
|
||||
span.exportable(false);
|
||||
}
|
||||
String processId = getHeader(request, response, Trace.PROCESS_ID_NAME);
|
||||
String parentName = getHeader(request, response, Trace.SPAN_NAME_NAME);
|
||||
String processId = getHeader(request, response, Span.PROCESS_ID_NAME);
|
||||
String parentName = getHeader(request, response, Span.SPAN_NAME_NAME);
|
||||
if (StringUtils.hasText(parentName)) {
|
||||
span.name(parentName);
|
||||
} else {
|
||||
@@ -140,26 +138,27 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
if (StringUtils.hasText(processId)) {
|
||||
span.processId(processId);
|
||||
}
|
||||
if (hasHeader(request, response, Trace.PARENT_ID_NAME)) {
|
||||
span.parent(Span.IdConverter.fromHex(getHeader(request, response, Trace.PARENT_ID_NAME)));
|
||||
if (hasHeader(request, response, Span.PARENT_ID_NAME)) {
|
||||
span.parent(
|
||||
Span.fromHex(getHeader(request, response, Span.PARENT_ID_NAME)));
|
||||
}
|
||||
span.remote(true);
|
||||
|
||||
Span parent = span.build();
|
||||
trace = this.tracer.joinTrace(name, parent);
|
||||
publish(new ServerReceivedEvent(this, parent, trace.getSpan()));
|
||||
request.setAttribute(TRACE_REQUEST_ATTR, trace);
|
||||
spanFromRequest = this.tracer.joinTrace(name, parent);
|
||||
publish(new ServerReceivedEvent(this, parent, spanFromRequest));
|
||||
request.setAttribute(TRACE_REQUEST_ATTR, spanFromRequest);
|
||||
|
||||
}
|
||||
else {
|
||||
if (skip) {
|
||||
trace = this.tracer.startTrace(name, IsTracingSampler.INSTANCE
|
||||
spanFromRequest = this.tracer.startTrace(name, IsTracingSampler.INSTANCE
|
||||
);
|
||||
}
|
||||
else {
|
||||
trace = this.tracer.startTrace(name);
|
||||
spanFromRequest = this.tracer.startTrace(name);
|
||||
}
|
||||
request.setAttribute(TRACE_REQUEST_ATTR, trace);
|
||||
request.setAttribute(TRACE_REQUEST_ATTR, spanFromRequest);
|
||||
}
|
||||
|
||||
Throwable exception = null;
|
||||
@@ -179,25 +178,25 @@ public class TraceFilter extends OncePerRequestFilter
|
||||
return;
|
||||
}
|
||||
if (skip) {
|
||||
addToResponseIfNotPresent(response, Trace.NOT_SAMPLED_NAME, "");
|
||||
addToResponseIfNotPresent(response, Span.NOT_SAMPLED_NAME, "");
|
||||
}
|
||||
if (trace != null) {
|
||||
if (spanFromRequest != null) {
|
||||
addResponseTags(response, exception);
|
||||
addResponseHeaders(response, trace.getSpan());
|
||||
if (trace.getSaved() != null) {
|
||||
publish(new ServerSentEvent(this, trace.getSaved().getSpan(),
|
||||
trace.getSpan()));
|
||||
addResponseHeaders(response, spanFromRequest);
|
||||
if (spanFromRequest.hasSavedSpan()) {
|
||||
publish(new ServerSentEvent(this, spanFromRequest.getSavedSpan(),
|
||||
spanFromRequest));
|
||||
}
|
||||
// Double close to clean up the parent (remote span as well)
|
||||
this.tracer.close(this.tracer.close(trace));
|
||||
this.tracer.close(this.tracer.close(spanFromRequest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addResponseHeaders(HttpServletResponse response, Span span) {
|
||||
if (span != null) {
|
||||
response.addHeader(Trace.SPAN_ID_NAME, Span.IdConverter.toHex(span.getSpanId()));
|
||||
response.addHeader(Trace.TRACE_ID_NAME, Span.IdConverter.toHex(span.getTraceId()));
|
||||
response.addHeader(Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));
|
||||
response.addHeader(Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -42,8 +42,8 @@ public class TraceHandlerInterceptor implements HandlerInterceptor {
|
||||
Object handler) throws Exception {
|
||||
// TODO: get trace data from request?
|
||||
// TODO: what is the description?
|
||||
Trace trace = this.tracer.startTrace("traceHandlerInterceptor");
|
||||
request.setAttribute(ATTR_NAME, trace);
|
||||
Span span = this.tracer.startTrace("traceHandlerInterceptor");
|
||||
request.setAttribute(ATTR_NAME, span);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class TraceHandlerInterceptor implements HandlerInterceptor {
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Exception ex) throws Exception {
|
||||
Trace trace = Trace.class.cast(request.getAttribute(ATTR_NAME));
|
||||
this.tracer.close(trace);
|
||||
Span span = Span.class.cast(request.getAttribute(ATTR_NAME));
|
||||
this.tracer.close(span);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringDecoder;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
@@ -123,14 +122,14 @@ public class TraceFeignClientAutoConfiguration {
|
||||
public void apply(RequestTemplate template) {
|
||||
Span span = getCurrentSpan();
|
||||
if (span == null) {
|
||||
setHeader(template, Trace.NOT_SAMPLED_NAME, "");
|
||||
setHeader(template, Span.NOT_SAMPLED_NAME, "");
|
||||
return;
|
||||
}
|
||||
template.header(Trace.TRACE_ID_NAME, Span.IdConverter.toHex(span.getTraceId()));
|
||||
setHeader(template, Trace.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(template, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(template, Trace.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(template, Trace.PROCESS_ID_NAME, span.getProcessId());
|
||||
template.header(Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
setHeader(template, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(template, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(template, Span.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(template, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
publish(new ClientSentEvent(this, span));
|
||||
}
|
||||
};
|
||||
@@ -156,7 +155,7 @@ public class TraceFeignClientAutoConfiguration {
|
||||
|
||||
public void setHeader(RequestTemplate request, String name, Long value) {
|
||||
if (value != null) {
|
||||
setHeader(request, name, Span.IdConverter.toHex(value));
|
||||
setHeader(request, name, Span.toHex(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,12 +165,12 @@ public class TraceFeignClientAutoConfiguration {
|
||||
newHeaders.putAll(headers);
|
||||
Span span = getCurrentSpan();
|
||||
if (span == null) {
|
||||
setHeader(newHeaders, Trace.NOT_SAMPLED_NAME, "");
|
||||
setHeader(newHeaders, Span.NOT_SAMPLED_NAME, "");
|
||||
return newHeaders;
|
||||
}
|
||||
setHeader(newHeaders, Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(newHeaders, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(newHeaders, Trace.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(newHeaders, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(newHeaders, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(newHeaders, Span.PARENT_ID_NAME, getParentId(span));
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
@@ -184,7 +183,7 @@ public class TraceFeignClientAutoConfiguration {
|
||||
public void setHeader(Map<String, Collection<String>> headers, String name,
|
||||
Long value) {
|
||||
if (value != null ){
|
||||
setHeader(headers, name, Span.IdConverter.toHex(value));
|
||||
setHeader(headers, name, Span.toHex(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.cloud.sleuth.instrument.web.client;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.event.ClientSentEvent;
|
||||
@@ -62,14 +61,14 @@ ApplicationEventPublisherAware {
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
Span span = getCurrentSpan();
|
||||
if (span == null) {
|
||||
setHeader(request, Trace.NOT_SAMPLED_NAME, "");
|
||||
setHeader(request, Span.NOT_SAMPLED_NAME, "");
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
setHeader(request, Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(request, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(request, Trace.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(request, Trace.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(request, Trace.PROCESS_ID_NAME, span.getProcessId());
|
||||
setHeader(request, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(request, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(request, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(request, Span.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(request, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
publish(new ClientSentEvent(this, span));
|
||||
return new TraceHttpResponse(this, execution.execute(request, body));
|
||||
}
|
||||
@@ -100,7 +99,7 @@ ApplicationEventPublisherAware {
|
||||
|
||||
public void setHeader(HttpRequest request, String name, Long value) {
|
||||
if (value != null) {
|
||||
setHeader(request, name, Span.IdConverter.toHex(value));
|
||||
setHeader(request, name, Span.toHex(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.springframework.cloud.sleuth.instrument.zuul;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.event.ClientSentEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -61,15 +60,15 @@ ApplicationEventPublisherAware {
|
||||
// N.B. this will only work with the simple host filter (not ribbon) unless you set hystrix.execution.isolation.strategy=SEMAPHORE
|
||||
Span span = getCurrentSpan();
|
||||
if (span == null) {
|
||||
setHeader(response, Trace.NOT_SAMPLED_NAME, "");
|
||||
setHeader(response, Span.NOT_SAMPLED_NAME, "");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
setHeader(response, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(response, Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(response, Trace.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(response, Trace.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(response, Trace.PROCESS_ID_NAME, span.getProcessId());
|
||||
setHeader(response, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(response, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(response, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(response, Span.PARENT_ID_NAME, getParentId(span));
|
||||
setHeader(response, Span.PROCESS_ID_NAME, span.getProcessId());
|
||||
// TODO: the client sent event should come from the client not the filter!
|
||||
publish(new ClientSentEvent(this, span));
|
||||
}
|
||||
@@ -94,7 +93,7 @@ ApplicationEventPublisherAware {
|
||||
}
|
||||
}
|
||||
public void setHeader(Map<String, String> request, String name, Long value) {
|
||||
setHeader(request, name, Span.IdConverter.toHex(value));
|
||||
setHeader(request, name, Span.toHex(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonComm
|
||||
import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory;
|
||||
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.event.ClientSentEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -91,15 +90,15 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand
|
||||
protected void customizeRequest(HttpRequest.Builder requestBuilder) {
|
||||
Span span = getCurrentSpan();
|
||||
if (span == null) {
|
||||
setHeader(requestBuilder, Trace.NOT_SAMPLED_NAME, "");
|
||||
setHeader(requestBuilder, Span.NOT_SAMPLED_NAME, "");
|
||||
return;
|
||||
}
|
||||
setHeader(requestBuilder, Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(requestBuilder, Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(requestBuilder, Trace.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(requestBuilder, Trace.PARENT_ID_NAME,
|
||||
setHeader(requestBuilder, Span.TRACE_ID_NAME, span.getTraceId());
|
||||
setHeader(requestBuilder, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(requestBuilder, Span.SPAN_NAME_NAME, span.getName());
|
||||
setHeader(requestBuilder, Span.PARENT_ID_NAME,
|
||||
getParentId(span));
|
||||
setHeader(requestBuilder, Trace.PROCESS_ID_NAME,
|
||||
setHeader(requestBuilder, Span.PROCESS_ID_NAME,
|
||||
span.getProcessId());
|
||||
publish(new ClientSentEvent(this, span));
|
||||
}
|
||||
@@ -122,7 +121,7 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand
|
||||
}
|
||||
|
||||
public void setHeader(HttpRequest.Builder builder, String name, Long value) {
|
||||
setHeader(builder, name, Span.IdConverter.toHex(value));
|
||||
setHeader(builder, name, Span.toHex(value));
|
||||
}
|
||||
|
||||
private Span getCurrentSpan() {
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.log;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanContinuedEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
@@ -26,8 +26,6 @@ import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -38,9 +36,9 @@ public class Slf4jSpanListener {
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
public void start(SpanAcquiredEvent event) {
|
||||
Span span = event.getSpan();
|
||||
MDC.put(Trace.SPAN_ID_NAME, Span.IdConverter.toHex(span.getSpanId()));
|
||||
MDC.put(Trace.SPAN_EXPORT_NAME, String.valueOf(span.isExportable()));
|
||||
MDC.put(Trace.TRACE_ID_NAME, Span.IdConverter.toHex(span.getTraceId()));
|
||||
MDC.put(Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));
|
||||
MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(span.isExportable()));
|
||||
MDC.put(Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
log.trace("Starting span: {}", span);
|
||||
if (event.getParent() != null) {
|
||||
log.trace("With parent: {}", event.getParent());
|
||||
@@ -51,9 +49,9 @@ public class Slf4jSpanListener {
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
public void continued(SpanContinuedEvent event) {
|
||||
Span span = event.getSpan();
|
||||
MDC.put(Trace.SPAN_ID_NAME, Span.IdConverter.toHex(span.getSpanId()));
|
||||
MDC.put(Trace.TRACE_ID_NAME, Span.IdConverter.toHex(span.getTraceId()));
|
||||
MDC.put(Trace.SPAN_EXPORT_NAME, String.valueOf(span.isExportable()));
|
||||
MDC.put(Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));
|
||||
MDC.put(Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
|
||||
MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(span.isExportable()));
|
||||
log.trace("Continued span: {}", event.getSpan());
|
||||
}
|
||||
|
||||
@@ -63,13 +61,13 @@ public class Slf4jSpanListener {
|
||||
log.trace("Stopped span: {}", event.getSpan());
|
||||
if (event.getParent() != null) {
|
||||
log.trace("With parent: {}", event.getParent());
|
||||
MDC.put(Trace.SPAN_ID_NAME, Span.IdConverter.toHex(event.getParent().getSpanId()));
|
||||
MDC.put(Trace.SPAN_EXPORT_NAME, String.valueOf(event.getParent().isExportable()));
|
||||
MDC.put(Span.SPAN_ID_NAME, Span.toHex(event.getParent().getSpanId()));
|
||||
MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(event.getParent().isExportable()));
|
||||
}
|
||||
else {
|
||||
MDC.remove(Trace.SPAN_ID_NAME);
|
||||
MDC.remove(Trace.SPAN_EXPORT_NAME);
|
||||
MDC.remove(Trace.TRACE_ID_NAME);
|
||||
MDC.remove(Span.SPAN_ID_NAME);
|
||||
MDC.remove(Span.SPAN_EXPORT_NAME);
|
||||
MDC.remove(Span.TRACE_ID_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.springframework.cloud.sleuth.Sampler;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AlwaysSampler implements Sampler<Void> {
|
||||
public class AlwaysSampler implements Sampler {
|
||||
@Override
|
||||
public boolean next() {
|
||||
return true;
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
package org.springframework.cloud.sleuth.sampler;
|
||||
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class IsTracingSampler implements Sampler<Void> {
|
||||
public class IsTracingSampler implements Sampler {
|
||||
|
||||
public static IsTracingSampler INSTANCE = new IsTracingSampler();
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
return TraceContextHolder.isTracing();
|
||||
return SpanContextHolder.isTracing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class PercentageBasedSampler implements Sampler<Void> {
|
||||
public class PercentageBasedSampler implements Sampler {
|
||||
|
||||
private final SamplerConfiguration configuration;
|
||||
private final TraceAccessor traceAccessor;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.template;
|
||||
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
public interface TraceCallback<T> {
|
||||
T doInTrace(Trace trace);
|
||||
T doInTrace(Span span);
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.template;
|
||||
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceDelegate;
|
||||
|
||||
@@ -35,11 +35,11 @@ public class TraceTemplate implements TraceOperations {
|
||||
public <T> T trace(final TraceCallback<T> callback) {
|
||||
if (this.tracer.isTracing()) {
|
||||
DelegateCallback<T> delegate = new DelegateCallback<>(this.tracer);
|
||||
Trace trace = delegate.startSpan();
|
||||
Span span = delegate.startSpan();
|
||||
try {
|
||||
return callback.doInTrace(trace);
|
||||
return callback.doInTrace(span);
|
||||
} finally {
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
}
|
||||
} else {
|
||||
return callback.doInTrace(null);
|
||||
@@ -53,7 +53,7 @@ public class TraceTemplate implements TraceOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Trace startSpan() {
|
||||
protected Span startSpan() {
|
||||
return super.startSpan();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.trace;
|
||||
|
||||
import static org.springframework.cloud.sleuth.util.ExceptionUtils.warn;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanContinuedEvent;
|
||||
@@ -34,18 +27,23 @@ import org.springframework.cloud.sleuth.instrument.TraceRunnable;
|
||||
import org.springframework.cloud.sleuth.util.ExceptionUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static org.springframework.cloud.sleuth.util.ExceptionUtils.warn;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DefaultTracer implements Tracer {
|
||||
|
||||
private final Sampler<Void> defaultSampler;
|
||||
private final Sampler defaultSampler;
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
|
||||
private final Random random;
|
||||
|
||||
public DefaultTracer(Sampler<Void> defaultSampler,
|
||||
public DefaultTracer(Sampler defaultSampler,
|
||||
Random random, ApplicationEventPublisher publisher) {
|
||||
this.defaultSampler = defaultSampler;
|
||||
this.random = random;
|
||||
@@ -53,13 +51,13 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace joinTrace(String name, Span parent) {
|
||||
public Span joinTrace(String name, Span parent) {
|
||||
if (parent == null) {
|
||||
return startTrace(name);
|
||||
}
|
||||
Span currentSpan = getCurrentSpan();
|
||||
if (currentSpan != null && !parent.equals(currentSpan)) {
|
||||
warn("Trace client warn: thread " + Thread.currentThread().getName()
|
||||
warn("Warn during joining trace: thread " + Thread.currentThread().getName()
|
||||
+ " tried to start a new Span " + "with parent " + parent.toString()
|
||||
+ ", but there is already a " + "currentSpan " + currentSpan);
|
||||
}
|
||||
@@ -67,20 +65,20 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace startTrace(String name) {
|
||||
public Span startTrace(String name) {
|
||||
return this.startTrace(name, this.defaultSampler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Trace startTrace(String name, Sampler<T> s) {
|
||||
Span span = null;
|
||||
public Span startTrace(String name, Sampler s) {
|
||||
Span span;
|
||||
if (isTracing() || s.next()) {
|
||||
span = createChild(getCurrentSpan(), name);
|
||||
}
|
||||
else {
|
||||
// Non-exportable so we keep the trace but not other data
|
||||
long id = createId();
|
||||
span = MilliSpan.builder().begin(System.currentTimeMillis()).name(name)
|
||||
span = Span.builder().begin(System.currentTimeMillis()).name(name)
|
||||
.traceId(id).spanId(id).exportable(false).build();
|
||||
this.publisher.publishEvent(new SpanAcquiredEvent(this, span));
|
||||
}
|
||||
@@ -88,12 +86,11 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace detach(Trace trace) {
|
||||
if (trace == null) {
|
||||
public Span detach(Span span) {
|
||||
if (span == null) {
|
||||
return null;
|
||||
}
|
||||
Span cur = TraceContextHolder.getCurrentSpan();
|
||||
Span span = trace.getSpan();
|
||||
Span cur = SpanContextHolder.getCurrentSpan();
|
||||
if (cur != span) {
|
||||
ExceptionUtils.warn("Tried to detach trace span but "
|
||||
+ "it is not the current span for the '"
|
||||
@@ -101,24 +98,23 @@ public class DefaultTracer implements Tracer {
|
||||
+ ". You have " + "probably forgotten to close or detach " + cur);
|
||||
}
|
||||
else {
|
||||
if (trace.getSaved() != null) {
|
||||
TraceContextHolder.setCurrentTrace(trace.getSaved());
|
||||
if (span.hasSavedSpan()) {
|
||||
SpanContextHolder.setCurrentSpan(span.getSavedSpan());
|
||||
}
|
||||
else {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
}
|
||||
return trace.getSaved();
|
||||
return span.getSavedSpan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace close(Trace trace) {
|
||||
if (trace == null) {
|
||||
public Span close(Span span) {
|
||||
if (span == null) {
|
||||
return null;
|
||||
}
|
||||
Span cur = TraceContextHolder.getCurrentSpan();
|
||||
Span span = trace.getSpan();
|
||||
Trace savedTrace = trace.getSaved();
|
||||
Span cur = SpanContextHolder.getCurrentSpan();
|
||||
Span savedSpan = span.getSavedSpan();
|
||||
if (cur != span) {
|
||||
ExceptionUtils.warn("Tried to close trace span but "
|
||||
+ "it is not the current span for the '"
|
||||
@@ -126,42 +122,35 @@ public class DefaultTracer implements Tracer {
|
||||
+ ". You have " + "probably forgotten to close or detach " + cur);
|
||||
}
|
||||
else {
|
||||
if (span != null) {
|
||||
span.stop();
|
||||
if (savedTrace != null
|
||||
&& span.getParents().contains(savedTrace.getSpan().getSpanId())) {
|
||||
this.publisher.publishEvent(
|
||||
new SpanReleasedEvent(this, savedTrace.getSpan(), span));
|
||||
TraceContextHolder.setCurrentTrace(savedTrace);
|
||||
}
|
||||
else {
|
||||
if (!span.isRemote()) {
|
||||
this.publisher.publishEvent(new SpanReleasedEvent(this, span));
|
||||
}
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
}
|
||||
span.stop();
|
||||
if (savedSpan != null && span.getParents().contains(savedSpan.getSpanId())) {
|
||||
this.publisher.publishEvent(new SpanReleasedEvent(this, savedSpan, span));
|
||||
SpanContextHolder.setCurrentSpan(savedSpan);
|
||||
}
|
||||
else {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
if (!span.isRemote()) {
|
||||
this.publisher.publishEvent(new SpanReleasedEvent(this, span));
|
||||
}
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
}
|
||||
return savedTrace;
|
||||
return savedSpan;
|
||||
}
|
||||
|
||||
protected Span createChild(Span parent, String name) {
|
||||
long id = createId();
|
||||
if (parent == null) {
|
||||
MilliSpan span = MilliSpan.builder().begin(System.currentTimeMillis())
|
||||
Span span = Span.builder().begin(System.currentTimeMillis())
|
||||
.name(name).traceId(id).spanId(id).build();
|
||||
this.publisher.publishEvent(new SpanAcquiredEvent(this, span));
|
||||
return span;
|
||||
}
|
||||
else {
|
||||
if (TraceContextHolder.getCurrentTrace() == null) {
|
||||
Trace trace = createTrace(null, parent);
|
||||
TraceContextHolder.setCurrentTrace(trace);
|
||||
if (SpanContextHolder.getCurrentSpan() == null) {
|
||||
Span span = createSpan(null, parent);
|
||||
SpanContextHolder.setCurrentSpan(span);
|
||||
}
|
||||
MilliSpan span = MilliSpan.builder().begin(System.currentTimeMillis())
|
||||
Span span = Span.builder().begin(System.currentTimeMillis())
|
||||
.name(name).traceId(parent.getTraceId()).parent(parent.getSpanId())
|
||||
.spanId(id).processId(parent.getProcessId()).build();
|
||||
this.publisher.publishEvent(new SpanAcquiredEvent(this, parent, span));
|
||||
@@ -174,27 +163,27 @@ public class DefaultTracer implements Tracer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace continueSpan(Span span) {
|
||||
public Span continueSpan(Span span) {
|
||||
if (span != null) {
|
||||
this.publisher.publishEvent(new SpanContinuedEvent(this, span));
|
||||
}
|
||||
Trace trace = createTrace(TraceContextHolder.getCurrentTrace(), span);
|
||||
TraceContextHolder.setCurrentTrace(trace);
|
||||
return trace;
|
||||
Span newSpan = createSpan(SpanContextHolder.getCurrentSpan(), span);
|
||||
SpanContextHolder.setCurrentSpan(newSpan);
|
||||
return newSpan;
|
||||
}
|
||||
|
||||
protected Trace createTrace(Trace trace, Span span) {
|
||||
return new Trace(trace, span);
|
||||
protected Span createSpan(Span saved, Span span) {
|
||||
return new Span(span, saved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span getCurrentSpan() {
|
||||
return TraceContextHolder.getCurrentSpan();
|
||||
return SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTracing() {
|
||||
return TraceContextHolder.isTracing();
|
||||
return SpanContextHolder.isTracing();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,45 +16,39 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.trace;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class TraceContextHolder {
|
||||
public class SpanContextHolder {
|
||||
|
||||
private static final ThreadLocal<Trace> currentTrace = new NamedThreadLocal<>("Trace Context");
|
||||
|
||||
public static Trace getCurrentTrace() {
|
||||
return currentTrace.get();
|
||||
}
|
||||
private static final ThreadLocal<Span> CURRENT_SPAN = new NamedThreadLocal<>("Trace Context");
|
||||
|
||||
public static Span getCurrentSpan() {
|
||||
return isTracing() ? currentTrace.get().getSpan() : null;
|
||||
return isTracing() ? CURRENT_SPAN.get() : null;
|
||||
}
|
||||
|
||||
public static void setCurrentTrace(Trace trace) {
|
||||
public static void setCurrentSpan(Span span) {
|
||||
// backwards compatibility
|
||||
if (trace == null) {
|
||||
currentTrace.remove();
|
||||
if (span == null) {
|
||||
CURRENT_SPAN.remove();
|
||||
return;
|
||||
}
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Setting current trace " + trace);
|
||||
log.trace("Setting current span " + span);
|
||||
}
|
||||
currentTrace.set(trace);
|
||||
CURRENT_SPAN.set(span);
|
||||
}
|
||||
|
||||
public static void removeCurrentTrace() {
|
||||
currentTrace.remove();
|
||||
public static void removeCurrentSpan() {
|
||||
CURRENT_SPAN.remove();
|
||||
}
|
||||
|
||||
public static boolean isTracing() {
|
||||
return currentTrace.get() != null;
|
||||
return CURRENT_SPAN.get() != null;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
@@ -53,12 +53,12 @@ public class DefaultTraceManagerTests {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clean() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -67,12 +67,12 @@ public class DefaultTraceManagerTests {
|
||||
|
||||
DefaultTracer traceManager = new DefaultTracer(new IsTracingSampler(), new Random(), publisher);
|
||||
|
||||
Trace trace = traceManager.startTrace(CREATE_SIMPLE_TRACE, new AlwaysSampler());
|
||||
Span span = traceManager.startTrace(CREATE_SIMPLE_TRACE, new AlwaysSampler());
|
||||
try {
|
||||
importantWork1(traceManager);
|
||||
}
|
||||
finally {
|
||||
traceManager.close(trace);
|
||||
traceManager.close(span);
|
||||
}
|
||||
|
||||
verify(publisher, times(NUM_SPANS)).publishEvent(isA(SpanAcquiredEvent.class));
|
||||
@@ -122,7 +122,7 @@ public class DefaultTraceManagerTests {
|
||||
}
|
||||
|
||||
private void importantWork1(Tracer tracer) {
|
||||
Trace cur = tracer.startTrace(IMPORTANT_WORK_1);
|
||||
Span cur = tracer.startTrace(IMPORTANT_WORK_1);
|
||||
try {
|
||||
Thread.sleep((long) (50 * Math.random()));
|
||||
importantWork2(tracer);
|
||||
@@ -136,7 +136,7 @@ public class DefaultTraceManagerTests {
|
||||
}
|
||||
|
||||
private void importantWork2(Tracer tracer) {
|
||||
Trace cur = tracer.startTrace(IMPORTANT_WORK_2);
|
||||
Span cur = tracer.startTrace(IMPORTANT_WORK_2);
|
||||
try {
|
||||
Thread.sleep((long) (50 * Math.random()));
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class MilliSpanTests {
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void getAnnotationsReadOnly() {
|
||||
MilliSpan span = new MilliSpan(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true, true, "process");
|
||||
|
||||
span.tags().put("a", "b");
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void getTimelineAnnotationsReadOnly() {
|
||||
MilliSpan span = new MilliSpan(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true, true, "process");
|
||||
|
||||
span.logs().add(new Log(1, "1"));
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,14 @@ package org.springframework.cloud.sleuth;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Rob Winch
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpanTest {
|
||||
|
||||
@@ -13,7 +17,7 @@ public class SpanTest {
|
||||
public void should_convert_long_to_hex_string() throws Exception {
|
||||
long someLong = 123123L;
|
||||
|
||||
String hexString = Span.IdConverter.toHex(someLong);
|
||||
String hexString = Span.toHex(someLong);
|
||||
|
||||
then(hexString).isEqualTo("1e0f3");
|
||||
}
|
||||
@@ -22,13 +26,27 @@ public class SpanTest {
|
||||
public void should_convert_hex_string_to_long() throws Exception {
|
||||
String hexString = "1e0f3";
|
||||
|
||||
long someLong = Span.IdConverter.fromHex(hexString);
|
||||
long someLong = Span.fromHex(hexString);
|
||||
|
||||
then(someLong).isEqualTo(123123L);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void should_throw_exception_when_null_string_is_to_be_converted_to_long() throws Exception {
|
||||
Span.IdConverter.fromHex(null);
|
||||
Span.fromHex(null);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class) public void getAnnotationsReadOnly() {
|
||||
Span span = new Span(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
true, "process");
|
||||
|
||||
span.tags().put("a", "b");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class) public void getTimelineAnnotationsReadOnly() {
|
||||
Span span = new Span(1, 2, "name", 1L, Collections.<Long>emptyList(), 2L, true,
|
||||
true, "process");
|
||||
|
||||
span.logs().add(new Log(1, "1"));
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,11 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
@@ -28,21 +28,21 @@ public class TraceCallableTests {
|
||||
|
||||
@After
|
||||
public void clean() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_not_see_same_trace_id_in_successive_tasks()
|
||||
throws Exception {
|
||||
Trace firstTrace = givenCallableGetsSubmitted(
|
||||
Span firstSpan = givenCallableGetsSubmitted(
|
||||
thatRetrievesTraceFromThreadLocal());
|
||||
|
||||
Trace secondTrace = whenCallableGetsSubmitted(
|
||||
Span secondSpan = whenCallableGetsSubmitted(
|
||||
thatRetrievesTraceFromThreadLocal());
|
||||
|
||||
then(secondTrace.getSpan().getTraceId())
|
||||
.isNotEqualTo(firstTrace.getSpan().getTraceId());
|
||||
then(secondTrace.getSaved()).isNull();
|
||||
then(secondSpan.getTraceId())
|
||||
.isNotEqualTo(firstSpan.getTraceId());
|
||||
then(secondSpan.getSavedSpan()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -50,51 +50,51 @@ public class TraceCallableTests {
|
||||
throws Exception {
|
||||
givenCallableGetsSubmitted(thatRetrievesTraceFromThreadLocal());
|
||||
|
||||
Trace secondTrace = whenNonTraceableCallableGetsSubmitted(
|
||||
Span secondSpan = whenNonTraceableCallableGetsSubmitted(
|
||||
thatRetrievesTraceFromThreadLocal());
|
||||
|
||||
then(secondTrace).isNull();
|
||||
then(secondSpan).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_remove_parent_span_from_thread_local_after_finishing_work()
|
||||
throws Exception {
|
||||
Trace parent = givenSpanIsAlreadyActive();
|
||||
Trace child = givenCallableGetsSubmitted(thatRetrievesTraceFromThreadLocal());
|
||||
Span parent = givenSpanIsAlreadyActive();
|
||||
Span child = givenCallableGetsSubmitted(thatRetrievesTraceFromThreadLocal());
|
||||
then(parent).as("parent").isNotNull();
|
||||
then(child.getSaved()).isEqualTo(parent);
|
||||
then(child.getSavedSpan()).isEqualTo(parent);
|
||||
|
||||
Trace secondTrace = whenNonTraceableCallableGetsSubmitted(
|
||||
Span secondSpan = whenNonTraceableCallableGetsSubmitted(
|
||||
thatRetrievesTraceFromThreadLocal());
|
||||
|
||||
then(secondTrace).isNull();
|
||||
then(secondSpan).isNull();
|
||||
}
|
||||
|
||||
private Trace givenSpanIsAlreadyActive() {
|
||||
private Span givenSpanIsAlreadyActive() {
|
||||
return this.tracer.startTrace("parent");
|
||||
}
|
||||
|
||||
private Callable<Trace> thatRetrievesTraceFromThreadLocal() {
|
||||
return new Callable<Trace>() {
|
||||
private Callable<Span> thatRetrievesTraceFromThreadLocal() {
|
||||
return new Callable<Span>() {
|
||||
@Override
|
||||
public Trace call() throws Exception {
|
||||
return TraceContextHolder.getCurrentTrace();
|
||||
public Span call() throws Exception {
|
||||
return SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Trace givenCallableGetsSubmitted(Callable<Trace> callable)
|
||||
private Span givenCallableGetsSubmitted(Callable<Span> callable)
|
||||
throws InterruptedException, java.util.concurrent.ExecutionException {
|
||||
return whenCallableGetsSubmitted(callable);
|
||||
}
|
||||
|
||||
private Trace whenCallableGetsSubmitted(Callable<Trace> callable)
|
||||
private Span whenCallableGetsSubmitted(Callable<Span> callable)
|
||||
throws InterruptedException, java.util.concurrent.ExecutionException {
|
||||
return this.executor.submit(new TraceCallable<>(this.tracer, callable))
|
||||
.get();
|
||||
}
|
||||
|
||||
private Trace whenNonTraceableCallableGetsSubmitted(Callable<Trace> callable)
|
||||
private Span whenNonTraceableCallableGetsSubmitted(Callable<Span> callable)
|
||||
throws InterruptedException, java.util.concurrent.ExecutionException {
|
||||
return this.executor.submit(callable).get();
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TraceRunnableTests {
|
||||
|
||||
@@ -27,7 +27,7 @@ public class TraceRunnableTests {
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -36,19 +36,19 @@ public class TraceRunnableTests {
|
||||
// given
|
||||
TraceKeepingRunnable traceKeepingRunnable = runnableThatRetrievesTraceFromThreadLocal();
|
||||
givenRunnableGetsSubmitted(traceKeepingRunnable);
|
||||
Trace firstTrace = traceKeepingRunnable.trace;
|
||||
then(firstTrace).as("first trace").isNotNull();
|
||||
Span firstSpan = traceKeepingRunnable.span;
|
||||
then(firstSpan).as("first span").isNotNull();
|
||||
|
||||
// when
|
||||
whenRunnableGetsSubmitted(traceKeepingRunnable);
|
||||
|
||||
// then
|
||||
Trace secondTrace = traceKeepingRunnable.trace;
|
||||
then(secondTrace.getSpan().getTraceId()).as("second trace id")
|
||||
.isNotEqualTo(firstTrace.getSpan().getTraceId()).as("first trace id");
|
||||
Span secondSpan = traceKeepingRunnable.span;
|
||||
then(secondSpan.getTraceId()).as("second span id")
|
||||
.isNotEqualTo(firstSpan.getTraceId()).as("first span id");
|
||||
|
||||
// and
|
||||
then(secondTrace.getSaved()).as("saved trace as remnant of first trace")
|
||||
then(secondSpan.getSavedSpan()).as("saved span as remnant of first span")
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@@ -58,15 +58,15 @@ public class TraceRunnableTests {
|
||||
// given
|
||||
TraceKeepingRunnable traceKeepingRunnable = runnableThatRetrievesTraceFromThreadLocal();
|
||||
givenRunnableGetsSubmitted(traceKeepingRunnable);
|
||||
Trace firstTrace = traceKeepingRunnable.trace;
|
||||
then(firstTrace).as("expected trace").isNotNull();
|
||||
Span firstSpan = traceKeepingRunnable.span;
|
||||
then(firstSpan).as("expected span").isNotNull();
|
||||
|
||||
// when
|
||||
whenNonTraceableRunnableGetsSubmitted(traceKeepingRunnable);
|
||||
|
||||
// then
|
||||
Trace secondTrace = traceKeepingRunnable.trace;
|
||||
then(secondTrace).as("unexpected trace").isNull();
|
||||
Span secondSpan = traceKeepingRunnable.span;
|
||||
then(secondSpan).as("unexpected span").isNull();
|
||||
}
|
||||
|
||||
private TraceKeepingRunnable runnableThatRetrievesTraceFromThreadLocal() {
|
||||
@@ -87,11 +87,11 @@ public class TraceRunnableTests {
|
||||
}
|
||||
|
||||
static class TraceKeepingRunnable implements Runnable {
|
||||
public Trace trace;
|
||||
public Span span;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
this.trace = TraceContextHolder.getCurrentTrace();
|
||||
this.span = SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
package org.springframework.cloud.sleuth.instrument.executor;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -12,21 +23,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TraceableExecutorServiceTests {
|
||||
@@ -42,7 +40,7 @@ public class TraceableExecutorServiceTests {
|
||||
public void setup() {
|
||||
this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
|
||||
this.traceManagerableExecutorService = new TraceableExecutorService(this.executorService, this.tracer);
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -50,17 +48,17 @@ public class TraceableExecutorServiceTests {
|
||||
this.tracer = null;
|
||||
this.traceManagerableExecutorService.shutdown();
|
||||
this.executorService.shutdown();
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void should_propagate_trace_id_and_set_new_span_when_traceable_executor_service_is_executed() {
|
||||
Trace trace = this.tracer.startTrace("PARENT");
|
||||
Span span = this.tracer.startTrace("PARENT");
|
||||
CompletableFuture.allOf(runnablesExecutedViaTraceManagerableExecutorService()).get();
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
|
||||
then(this.spanVerifyingRunnable.traceIds.stream().distinct().collect(toList())).containsOnly(trace.getSpan().getTraceId());
|
||||
then(this.spanVerifyingRunnable.traceIds.stream().distinct().collect(toList())).containsOnly(span.getTraceId());
|
||||
then(this.spanVerifyingRunnable.spanIds.stream().distinct().collect(toList())).hasSize(TOTAL_THREADS);
|
||||
}
|
||||
|
||||
@@ -79,7 +77,7 @@ public class TraceableExecutorServiceTests {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Span span = TraceContextHolder.getCurrentSpan();
|
||||
Span span = SpanContextHolder.getCurrentSpan();
|
||||
this.traceIds.add(span.getTraceId());
|
||||
this.spanIds.add(span.getSpanId());
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.springframework.cloud.netflix.hystrix.EnableHystrix;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -39,7 +39,7 @@ public class SpanPassingForHystrixViaAnnotationsIntegrationTests {
|
||||
}
|
||||
|
||||
private Span givenASpanInCurrentThread() {
|
||||
Span span = tracer.startTrace("existing").getSpan();
|
||||
Span span = tracer.startTrace("existing");
|
||||
tracer.continueSpan(span);
|
||||
return span;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class SpanPassingForHystrixViaAnnotationsIntegrationTests {
|
||||
|
||||
@After
|
||||
public void cleanTrace() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@DefaultTestAutoConfiguration
|
||||
@@ -81,7 +81,7 @@ public class SpanPassingForHystrixViaAnnotationsIntegrationTests {
|
||||
|
||||
@HystrixCommand
|
||||
public void invokeLogicWrappedInHystrixCommand() {
|
||||
spanCaughtFromHystrixThread = new AtomicReference<>(TraceContextHolder.getCurrentSpan());
|
||||
spanCaughtFromHystrixThread = new AtomicReference<>(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
public Long getTraceId() {
|
||||
|
||||
@@ -6,12 +6,11 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
@@ -28,64 +27,65 @@ public class TraceCommandTests {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_remove_span_from_thread_local_after_finishing_work()
|
||||
throws Exception {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
Trace firstTraceFromHystrix = givenACommandWasExecuted(traceReturningCommand());
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
Span firstSpanFromHystrix = givenACommandWasExecuted(traceReturningCommand());
|
||||
|
||||
Trace secondTraceFromHystrix = whenCommandIsExecuted(traceReturningCommand());
|
||||
Span secondSpanFromHystrix = whenCommandIsExecuted(traceReturningCommand());
|
||||
|
||||
then(secondTraceFromHystrix.getSpan().getTraceId()).as("second trace id")
|
||||
.isNotEqualTo(firstTraceFromHystrix.getSpan().getTraceId()).as("first trace id");
|
||||
then(secondTraceFromHystrix.getSaved()).as("saved trace as remnant of first trace")
|
||||
then(secondSpanFromHystrix.getTraceId()).as("second span id")
|
||||
.isNotEqualTo(firstSpanFromHystrix.getTraceId()).as("first span id");
|
||||
then(secondSpanFromHystrix.getSavedSpan()).as("saved span as remnant of first span")
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_run_Hystrix_command_with_span_passed_from_parent_thread() {
|
||||
givenATraceIsPresentInTheCurrentThread();
|
||||
TraceCommand<Trace> command = traceReturningCommand();
|
||||
TraceCommand<Span> command = traceReturningCommand();
|
||||
|
||||
Trace traceFromCommand = whenCommandIsExecuted(command);
|
||||
Span spanFromCommand = whenCommandIsExecuted(command);
|
||||
|
||||
then(traceFromCommand).as("Trace from the Hystrix Thread").isNotNull();
|
||||
then(traceFromCommand.getSpan().getTraceId()).isEqualTo(EXPECTED_TRACE_ID);
|
||||
then(spanFromCommand).as("Span from the Hystrix Thread").isNotNull();
|
||||
then(spanFromCommand.getTraceId()).isEqualTo(EXPECTED_TRACE_ID);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUpTrace() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
private Trace givenATraceIsPresentInTheCurrentThread() {
|
||||
return this.tracer.joinTrace("test", MilliSpan.builder().traceId(EXPECTED_TRACE_ID).build());
|
||||
private Span givenATraceIsPresentInTheCurrentThread() {
|
||||
return this.tracer
|
||||
.joinTrace("test", Span.builder().traceId(EXPECTED_TRACE_ID).build());
|
||||
}
|
||||
|
||||
private TraceCommand<Trace> traceReturningCommand() {
|
||||
return new TraceCommand<Trace>(this.tracer, withGroupKey(asKey(""))
|
||||
private TraceCommand<Span> traceReturningCommand() {
|
||||
return new TraceCommand<Span>(this.tracer, withGroupKey(asKey(""))
|
||||
.andCommandKey(HystrixCommandKey.Factory.asKey("")).andThreadPoolPropertiesDefaults(
|
||||
HystrixThreadPoolProperties.Setter().withMaxQueueSize(1).withCoreSize(1))) {
|
||||
@Override
|
||||
public Trace doRun() throws Exception {
|
||||
return TraceContextHolder.getCurrentTrace();
|
||||
public Span doRun() throws Exception {
|
||||
return SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Trace whenCommandIsExecuted(TraceCommand<Trace> command) {
|
||||
private Span whenCommandIsExecuted(TraceCommand<Span> command) {
|
||||
return command.execute();
|
||||
}
|
||||
|
||||
private Trace givenACommandWasExecuted(TraceCommand<Trace> command) {
|
||||
private Span givenACommandWasExecuted(TraceCommand<Span> command) {
|
||||
return whenCommandIsExecuted(command);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
package org.springframework.cloud.sleuth.instrument.integration;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public abstract class AbstractTraceStompIntegrationTests {
|
||||
|
||||
@@ -34,11 +34,11 @@ public abstract class AbstractTraceStompIntegrationTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
this.channel.unsubscribe(this.stompMessageHandler);
|
||||
}
|
||||
|
||||
Trace givenALocallyStartedSpan() {
|
||||
Span givenALocallyStartedSpan() {
|
||||
return this.tracer.startTrace("testSendMessage", this.sampler);
|
||||
}
|
||||
|
||||
@@ -52,13 +52,13 @@ public abstract class AbstractTraceStompIntegrationTests {
|
||||
}
|
||||
|
||||
Long thenSpanIdFromHeadersIsNotEmpty() {
|
||||
Long header = getValueFromHeaders(Trace.SPAN_ID_NAME, Long.class);
|
||||
Long header = getValueFromHeaders(Span.SPAN_ID_NAME, Long.class);
|
||||
then(header).as("Span id should not be empty").isNotNull();
|
||||
return header;
|
||||
}
|
||||
|
||||
Long thenTraceIdFromHeadersIsNotEmpty() {
|
||||
Long header = getValueFromHeaders(Trace.TRACE_ID_NAME, Long.class);
|
||||
Long header = getValueFromHeaders(Span.TRACE_ID_NAME, Long.class);
|
||||
then(header).as("Trace id should not be empty").isNotNull();
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -26,12 +26,11 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
import org.springframework.cloud.sleuth.instrument.integration.TraceChannelInterceptorTests.App;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
@@ -48,7 +47,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -79,7 +81,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
this.message = message;
|
||||
this.span = TraceContextHolder.getCurrentSpan();
|
||||
this.span = SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -89,35 +91,36 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
this.channel.unsubscribe(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonExportableSpanCreation() {
|
||||
this.channel.send(MessageBuilder.withPayload("hi").setHeader(Trace.NOT_SAMPLED_NAME, "")
|
||||
this.channel.send(MessageBuilder.withPayload("hi").setHeader(Span.NOT_SAMPLED_NAME, "")
|
||||
.build());
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
|
||||
assertNotNull("spanId was null", spanId);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
assertFalse(this.span.isExportable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parentSpanIncluded() {
|
||||
this.channel.send(MessageBuilder.withPayload("hi").setHeader(Trace.TRACE_ID_NAME, 10L)
|
||||
.setHeader(Trace.SPAN_ID_NAME, 20L)
|
||||
this.channel.send(MessageBuilder.withPayload("hi").setHeader(Span.TRACE_ID_NAME, 10L)
|
||||
.setHeader(Span.SPAN_ID_NAME, 20L)
|
||||
.build());
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
|
||||
assertNotNull("spanId was null", spanId);
|
||||
long traceId = Span.IdConverter.fromHex(this.message.getHeaders().get(Trace.TRACE_ID_NAME, String.class));
|
||||
long traceId = Span
|
||||
.fromHex(this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class));
|
||||
then(traceId).isEqualTo(10L);
|
||||
then(spanId).isNotEqualTo(20L);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
assertEquals(1, this.app.events.size());
|
||||
}
|
||||
|
||||
@@ -126,45 +129,45 @@ public class TraceChannelInterceptorTests implements MessageHandler {
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
|
||||
assertNotNull("spanId was null", spanId);
|
||||
|
||||
String traceId = this.message.getHeaders().get(Trace.TRACE_ID_NAME, String.class);
|
||||
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
|
||||
assertNotNull("traceId was null", traceId);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerCreation() {
|
||||
Trace trace = this.tracer.startTrace("testSendMessage",
|
||||
Span span = this.tracer.startTrace("testSendMessage",
|
||||
new AlwaysSampler());
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
|
||||
assertNotNull("spanId was null", spanId);
|
||||
|
||||
String traceId = this.message.getHeaders().get(Trace.TRACE_ID_NAME, String.class);
|
||||
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
|
||||
assertNotNull("traceId was null", traceId);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
// TODO: Refactor to parametrized test together with sending messages via channel
|
||||
@Test
|
||||
public void headerCreationViaMessagingTemplate() {
|
||||
Trace trace = this.tracer.startTrace("testSendMessage",
|
||||
Span span = this.tracer.startTrace("testSendMessage",
|
||||
new AlwaysSampler());
|
||||
this.messagingTemplate.send(MessageBuilder.withPayload("hi").build());
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
assertNotNull("message was null", this.message);
|
||||
|
||||
String spanId = this.message.getHeaders().get(Trace.SPAN_ID_NAME, String.class);
|
||||
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
|
||||
assertNotNull("spanId was null", spanId);
|
||||
|
||||
String traceId = this.message.getHeaders().get(Trace.TRACE_ID_NAME, String.class);
|
||||
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
|
||||
assertNotNull("traceId was null", traceId);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -25,11 +25,10 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.integration.TraceContextPropagationChannelInterceptorTests.App;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -60,25 +59,27 @@ public class TraceContextPropagationChannelInterceptorTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpanPropagation() {
|
||||
|
||||
Trace trace = this.tracer.startTrace("testSendMessage", new AlwaysSampler());
|
||||
Span span = this.tracer.startTrace("testSendMessage", new AlwaysSampler());
|
||||
this.channel.send(MessageBuilder.withPayload("hi").build());
|
||||
Long expectedSpanId = trace.getSpan().getSpanId();
|
||||
this.tracer.close(trace);
|
||||
Long expectedSpanId = span.getSpanId();
|
||||
this.tracer.close(span);
|
||||
|
||||
Message<?> message = this.channel.receive(0);
|
||||
|
||||
assertNotNull("message was null", message);
|
||||
|
||||
Long spanId = Span.IdConverter.fromHex(message.getHeaders().get(Trace.SPAN_ID_NAME, String.class));
|
||||
Long spanId = Span
|
||||
.fromHex(message.getHeaders().get(Span.SPAN_ID_NAME, String.class));
|
||||
assertEquals("spanId was wrong", expectedSpanId, spanId);
|
||||
|
||||
long traceId = Span.IdConverter.fromHex(message.getHeaders().get(Trace.TRACE_ID_NAME, String.class));
|
||||
long traceId = Span
|
||||
.fromHex(message.getHeaders().get(Span.TRACE_ID_NAME, String.class));
|
||||
assertNotNull("traceId was null", traceId);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.instrument.integration.TraceStompMessageChannelInterceptorTests.TestApplication;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -44,30 +44,30 @@ public class TraceStompMessageChannelInterceptorTests extends AbstractTraceStomp
|
||||
|
||||
thenSpanIdFromHeadersIsNotEmpty();
|
||||
thenTraceIdFromHeadersIsNotEmpty();
|
||||
then(TraceContextHolder.getCurrentTrace()).isNull();
|
||||
then(SpanContextHolder.getCurrentSpan()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_propagate_headers_when_message_was_sent_during_local_span_starting() {
|
||||
Trace trace = givenALocallyStartedSpan();
|
||||
Span span = givenALocallyStartedSpan();
|
||||
Message<?> message = givenMessageToBeSampled();
|
||||
|
||||
whenTheMessageWasSent(message);
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
|
||||
Long spanId = thenSpanIdFromHeadersIsNotEmpty();
|
||||
long traceId = thenTraceIdFromHeadersIsNotEmpty();
|
||||
then(traceId).isEqualTo(trace.getSpan().getTraceId());
|
||||
then(spanId).isEqualTo(trace.getSpan().getSpanId());
|
||||
then(TraceContextHolder.getCurrentTrace()).isNull();
|
||||
then(traceId).isEqualTo(span.getTraceId());
|
||||
then(spanId).isEqualTo(span.getSpanId());
|
||||
then(SpanContextHolder.getCurrentSpan()).isNull();
|
||||
}
|
||||
|
||||
private Message<?> givenMessageNotToBeSampled() {
|
||||
return StompMessageBuilder.fromMessage(new GenericMessage<>("Message2")).setHeader(Trace.NOT_SAMPLED_NAME, "").build();
|
||||
return StompMessageBuilder.fromMessage(new GenericMessage<>("Message2")).setHeader(Span.NOT_SAMPLED_NAME, "").build();
|
||||
}
|
||||
|
||||
private String thenSpanIdFromHeadersIsEmpty() {
|
||||
String header = getValueFromHeaders(Trace.SPAN_ID_NAME, String.class);
|
||||
String header = getValueFromHeaders(Span.SPAN_ID_NAME, String.class);
|
||||
then(header).as("Span id should be empty").isNullOrEmpty();
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.instrument.integration.TraceStompMessageContextPropagationChannelInterceptorTests.TestApplication;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -28,12 +28,12 @@ public class TraceStompMessageContextPropagationChannelInterceptorTests extends
|
||||
|
||||
@Test
|
||||
public void should_propagate_span_information() {
|
||||
Trace trace = givenALocallyStartedSpan();
|
||||
Span span = givenALocallyStartedSpan();
|
||||
Message<?> m = givenMessageToBeSampled();
|
||||
|
||||
whenTheMessageWasSent(m);
|
||||
Long expectedTraceId = trace.getSpan().getTraceId();
|
||||
this.tracer.close(trace);
|
||||
Long expectedTraceId = span.getTraceId();
|
||||
this.tracer.close(span);
|
||||
|
||||
thenReceivedMessageIsNotNull();
|
||||
long traceId = thenTraceIdFromHeadersIsNotEmpty();
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -70,7 +70,7 @@ class TestBeanWithScheduledMethod {
|
||||
|
||||
@Scheduled(fixedDelay = 1L)
|
||||
public void scheduledMethod() {
|
||||
this.span = TraceContextHolder.getCurrentSpan();
|
||||
this.span = SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
|
||||
public Span getSpan() {
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.common.HttpMockServer;
|
||||
import org.springframework.cloud.sleuth.instrument.web.common.AbstractMvcWiremockIntegrationTest;
|
||||
@@ -71,7 +71,7 @@ public class RestTemplateTraceAspectIntegrationTests extends AbstractMvcWiremock
|
||||
}
|
||||
|
||||
private void thenTraceIdHasBeenSetOnARequestHeader() {
|
||||
this.wireMock.verifyThat(getRequestedFor(urlMatching(".*")).withHeader(Trace.TRACE_ID_NAME, matching("^(?!\\s*$).+")));
|
||||
this.wireMock.verifyThat(getRequestedFor(urlMatching(".*")).withHeader(Span.TRACE_ID_NAME, matching("^(?!\\s*$).+")));
|
||||
}
|
||||
|
||||
private void whenARequestIsSentToAnAsyncEndpoint(String url) throws Exception {
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
@@ -40,7 +40,7 @@ public class TraceAsyncIntegrationTests {
|
||||
}
|
||||
|
||||
private Span givenASpanInCurrentThread() {
|
||||
Span span = tracer.startTrace("existing").getSpan();
|
||||
Span span = tracer.startTrace("existing");
|
||||
tracer.continueSpan(span);
|
||||
return span;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class TraceAsyncIntegrationTests {
|
||||
|
||||
@After
|
||||
public void cleanTrace() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@DefaultTestAutoConfiguration
|
||||
@@ -83,7 +83,7 @@ public class TraceAsyncIntegrationTests {
|
||||
|
||||
@Async
|
||||
public void invokeAsynchronousLogic() {
|
||||
span.set(TraceContextHolder.getCurrentSpan());
|
||||
span.set(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
public Long getTraceId() {
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
@@ -20,6 +15,10 @@ import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(TraceFilterIntegrationTests.class)
|
||||
@DefaultTestAutoConfiguration
|
||||
@@ -60,19 +59,19 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest {
|
||||
|
||||
private MvcResult whenSentPingWithTraceId(Long passedTraceId)
|
||||
throws Exception {
|
||||
return sendPingWithTraceId(Trace.TRACE_ID_NAME, passedTraceId);
|
||||
return sendPingWithTraceId(Span.TRACE_ID_NAME, passedTraceId);
|
||||
}
|
||||
|
||||
private MvcResult sendPingWithTraceId(String headerName, Long passedCorrelationId)
|
||||
throws Exception {
|
||||
return this.mockMvc
|
||||
.perform(MockMvcRequestBuilders.get("/ping").accept(MediaType.TEXT_PLAIN)
|
||||
.header(headerName, Span.IdConverter.toHex(passedCorrelationId))
|
||||
.header(Trace.SPAN_ID_NAME, Span.IdConverter.toHex(new Random().nextLong())))
|
||||
.header(headerName, Span.toHex(passedCorrelationId))
|
||||
.header(Span.SPAN_ID_NAME, Span.toHex(new Random().nextLong())))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
private Long tracingHeaderFrom(MvcResult mvcResult) {
|
||||
return Span.IdConverter.fromHex(mvcResult.getResponse().getHeader(Trace.TRACE_ID_NAME));
|
||||
return Span.fromHex(mvcResult.getResponse().getHeader(Span.TRACE_ID_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockFilterChain;
|
||||
@@ -37,7 +33,10 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -58,7 +57,7 @@ public class TraceFilterMockChainIntegrationTests {
|
||||
@Before
|
||||
@SneakyThrows
|
||||
public void init() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
this.context.refresh();
|
||||
this.request = builder().buildRequest(new MockServletContext());
|
||||
this.response = new MockHttpServletResponse();
|
||||
@@ -75,17 +74,17 @@ public class TraceFilterMockChainIntegrationTests {
|
||||
public void startsNewTrace() throws Exception {
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void continuesSpanFromHeaders() throws Exception {
|
||||
Random generator = new Random();
|
||||
this.request = builder().header(Trace.SPAN_ID_NAME, generator.nextLong())
|
||||
.header(Trace.TRACE_ID_NAME, generator.nextLong()).buildRequest(new MockServletContext());
|
||||
this.request = builder().header(Span.SPAN_ID_NAME, generator.nextLong())
|
||||
.header(Span.TRACE_ID_NAME, generator.nextLong()).buildRequest(new MockServletContext());
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
assertNull(TraceContextHolder.getCurrentSpan());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,28 +16,18 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -47,7 +37,15 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -65,7 +63,7 @@ public class TraceFilterTests {
|
||||
private MockHttpServletRequest request;
|
||||
private MockHttpServletResponse response;
|
||||
private MockFilterChain filterChain;
|
||||
private Sampler<Void> sampler = new AlwaysSampler();
|
||||
private Sampler sampler = new AlwaysSampler();
|
||||
|
||||
@Before
|
||||
@SneakyThrows
|
||||
@@ -74,9 +72,9 @@ public class TraceFilterTests {
|
||||
this.tracer = new DefaultTracer(new DelegateSampler(), new Random(),
|
||||
this.publisher) {
|
||||
@Override
|
||||
protected Trace createTrace(Trace trace, Span span) {
|
||||
TraceFilterTests.this.span = span;
|
||||
return super.createTrace(trace, span);
|
||||
protected Span createSpan(Span saved, Span span) {
|
||||
TraceFilterTests.this.span = super.createSpan(saved, span);
|
||||
return TraceFilterTests.this.span;
|
||||
}
|
||||
};
|
||||
this.request = builder().buildRequest(new MockServletContext());
|
||||
@@ -101,7 +99,7 @@ public class TraceFilterTests {
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
assertFalse(this.span.isExportable());
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,40 +107,40 @@ public class TraceFilterTests {
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
verifyHttpTags();
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void continuesSpanInRequestAttr() throws Exception {
|
||||
|
||||
Trace trace = this.tracer.startTrace("foo");
|
||||
this.request.setAttribute(TraceFilter.TRACE_REQUEST_ATTR, trace);
|
||||
Span span = this.tracer.startTrace("foo");
|
||||
this.request.setAttribute(TraceFilter.TRACE_REQUEST_ATTR, span);
|
||||
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
verifyHttpTags();
|
||||
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void continuesSpanFromHeaders() throws Exception {
|
||||
this.request = builder().header(Trace.SPAN_ID_NAME, 10L)
|
||||
.header(Trace.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
this.request = builder().header(Span.SPAN_ID_NAME, 10L)
|
||||
.header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
filter.doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
verifyHttpTags();
|
||||
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsAdditionalHeaders() throws Exception {
|
||||
this.request = builder().header(Trace.SPAN_ID_NAME, 10L)
|
||||
.header(Trace.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
this.request = builder().header(Span.SPAN_ID_NAME, 10L)
|
||||
.header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
|
||||
this.traceKeys.getHttp().getHeaders().add("x-foo");
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
@@ -151,13 +149,13 @@ public class TraceFilterTests {
|
||||
|
||||
assertThat(this.span.tags()).contains(entry("http/x-foo", "bar"));
|
||||
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void additionalMultiValuedHeader() throws Exception {
|
||||
this.request = builder().header(Trace.SPAN_ID_NAME, 10L)
|
||||
.header(Trace.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
this.request = builder().header(Span.SPAN_ID_NAME, 10L)
|
||||
.header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext());
|
||||
|
||||
this.traceKeys.getHttp().getHeaders().add("x-foo");
|
||||
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
|
||||
@@ -167,7 +165,7 @@ public class TraceFilterTests {
|
||||
|
||||
assertThat(this.span.tags()).contains(entry("http/x-foo", "'bar','spam'"));
|
||||
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -189,7 +187,7 @@ public class TraceFilterTests {
|
||||
}
|
||||
verifyHttpTags(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
assertNull(TraceContextHolder.getCurrentTrace());
|
||||
assertNull(SpanContextHolder.getCurrentSpan());
|
||||
}
|
||||
|
||||
public void verifyHttpTags() {
|
||||
@@ -216,7 +214,7 @@ public class TraceFilterTests {
|
||||
}
|
||||
}
|
||||
|
||||
private class DelegateSampler implements Sampler<Void> {
|
||||
private class DelegateSampler implements Sampler {
|
||||
@Override
|
||||
public boolean next() {
|
||||
return TraceFilterTests.this.sampler.next();
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package org.springframework.cloud.sleuth.instrument.web.client;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -18,13 +14,11 @@ import org.springframework.boot.test.WebIntegrationTest;
|
||||
import org.springframework.cloud.netflix.feign.EnableFeignClients;
|
||||
import org.springframework.cloud.netflix.feign.FeignClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
import org.springframework.cloud.sleuth.event.ClientSentEvent;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -38,9 +32,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = { FeignTraceTests.TestConfiguration.class })
|
||||
@@ -59,7 +56,7 @@ public class FeignTraceTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
this.listener.getEvents().clear();
|
||||
}
|
||||
|
||||
@@ -69,7 +66,7 @@ public class FeignTraceTests {
|
||||
ResponseEntity<String> response = this.testFeignInterface.getNoTrace();
|
||||
|
||||
// then
|
||||
then(getHeader(response, Trace.TRACE_ID_NAME)).isNotNull();
|
||||
then(getHeader(response, Span.TRACE_ID_NAME)).isNotNull();
|
||||
then(this.listener.getEvents()).isNotEmpty();
|
||||
}
|
||||
|
||||
@@ -78,14 +75,14 @@ public class FeignTraceTests {
|
||||
// given
|
||||
Long currentTraceId = 1L;
|
||||
Long currentParentId = 2L;
|
||||
this.tracer.continueSpan(MilliSpan.builder().traceId(currentTraceId)
|
||||
this.tracer.continueSpan(Span.builder().traceId(currentTraceId)
|
||||
.spanId(generatedId()).parent(currentParentId).build());
|
||||
|
||||
// when
|
||||
ResponseEntity<String> response = this.testFeignInterface.getTraceId();
|
||||
|
||||
// then
|
||||
then(Span.IdConverter.fromHex(getHeader(response, Trace.TRACE_ID_NAME))).isEqualTo(currentTraceId);
|
||||
then(Span.fromHex(getHeader(response, Span.TRACE_ID_NAME))).isEqualTo(currentTraceId);
|
||||
then(this.listener.getEvents().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@@ -148,15 +145,15 @@ public class FeignTraceTests {
|
||||
|
||||
@RequestMapping(value = "/notrace", method = RequestMethod.GET)
|
||||
public String notrace(
|
||||
@RequestHeader(name = Trace.TRACE_ID_NAME, required = false) String traceId) {
|
||||
@RequestHeader(name = Span.TRACE_ID_NAME, required = false) String traceId) {
|
||||
then(traceId).isNotNull();
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/traceid", method = RequestMethod.GET)
|
||||
public String traceId(@RequestHeader(Trace.TRACE_ID_NAME) String traceId,
|
||||
@RequestHeader(Trace.SPAN_ID_NAME) String spanId,
|
||||
@RequestHeader(Trace.PARENT_ID_NAME) String parentId) {
|
||||
public String traceId(@RequestHeader(Span.TRACE_ID_NAME) String traceId,
|
||||
@RequestHeader(Span.SPAN_ID_NAME) String spanId,
|
||||
@RequestHeader(Span.PARENT_ID_NAME) String parentId) {
|
||||
then(traceId).isNotEmpty();
|
||||
then(parentId).isNotEmpty();
|
||||
then(spanId).isNotEmpty();
|
||||
|
||||
@@ -16,22 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
@@ -43,6 +34,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -65,22 +64,22 @@ public class TraceRestTemplateInterceptorTests {
|
||||
this.traces = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
|
||||
this.template.setInterceptors(Arrays.<ClientHttpRequestInterceptor>asList(
|
||||
new TraceRestTemplateInterceptor(this.traces)));
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clean() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headersAddedWhenTracing() {
|
||||
this.traces.continueSpan(MilliSpan.builder().traceId(1L).spanId(2L).build());
|
||||
this.traces.continueSpan(Span.builder().traceId(1L).spanId(2L).build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> headers = this.template.getForEntity("/", Map.class)
|
||||
.getBody();
|
||||
then(Long.valueOf(headers.get(Trace.TRACE_ID_NAME))).isEqualTo(1L);
|
||||
then(Long.valueOf(headers.get(Trace.SPAN_ID_NAME))).isEqualTo(2L);
|
||||
then(Long.valueOf(headers.get(Span.TRACE_ID_NAME))).isEqualTo(1L);
|
||||
then(Long.valueOf(headers.get(Span.SPAN_ID_NAME))).isEqualTo(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,7 +87,7 @@ public class TraceRestTemplateInterceptorTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> headers = this.template.getForEntity("/", Map.class)
|
||||
.getBody();
|
||||
assertFalse("Wrong headers: " + headers, headers.containsKey(Trace.SPAN_ID_NAME));
|
||||
assertFalse("Wrong headers: " + headers, headers.containsKey(Span.SPAN_ID_NAME));
|
||||
}
|
||||
|
||||
@RestController
|
||||
@@ -96,8 +95,8 @@ public class TraceRestTemplateInterceptorTests {
|
||||
@RequestMapping("/")
|
||||
public Map<String, String> home(@RequestHeader HttpHeaders headers) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
addHeaders(map, headers, Trace.SPAN_ID_NAME, Trace.TRACE_ID_NAME,
|
||||
Trace.PARENT_ID_NAME);
|
||||
addHeaders(map, headers, Span.SPAN_ID_NAME, Span.TRACE_ID_NAME,
|
||||
Span.PARENT_ID_NAME);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.log;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.OutputCapture;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -38,7 +39,7 @@ public class JsonLogSpanListenerTests {
|
||||
@Test
|
||||
public void jsonSpanIsOnOneLine() throws IOException {
|
||||
JsonLogSpanListener listener = new JsonLogSpanListener();
|
||||
Span span = MilliSpan.builder()
|
||||
Span span = Span.builder()
|
||||
.name("testSpan")
|
||||
.spanId(1L)
|
||||
.parent(2L)
|
||||
@@ -61,7 +62,7 @@ public class JsonLogSpanListenerTests {
|
||||
assertFalse("json contains linefeed", output.contains("\n"));
|
||||
assertFalse("json contains carriage return", output.contains("\r"));
|
||||
|
||||
MilliSpan read = listener.getObjectMapper().readValue(json, MilliSpan.class);
|
||||
Span read = listener.getObjectMapper().readValue(json, Span.class);
|
||||
assertEquals("span not equals", read, span);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package org.springframework.cloud.sleuth.sampler;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.assertj.core.data.Percentage.withPercentage;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.assertj.core.data.Percentage.withPercentage;
|
||||
|
||||
public class PercentageBasedSamplerTests {
|
||||
|
||||
SamplerConfiguration samplerConfiguration = new SamplerConfiguration();
|
||||
@@ -59,7 +58,7 @@ public class PercentageBasedSamplerTests {
|
||||
return new TraceAccessor() {
|
||||
@Override
|
||||
public Span getCurrentSpan() {
|
||||
return MilliSpan.builder().traceId(RANDOM.nextLong()).build();
|
||||
return Span.builder().traceId(RANDOM.nextLong()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package org.springframework.cloud.sleuth.template;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
public class TraceTemplateTests {
|
||||
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(),
|
||||
@@ -21,25 +21,25 @@ public class TraceTemplateTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TraceContextHolder.removeCurrentTrace();
|
||||
SpanContextHolder.removeCurrentSpan();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_pass_trace_to_the_callback_if_tracing_is_active() {
|
||||
Trace initialTrace = this.tracer.startTrace("test");
|
||||
Span initialSpan = this.tracer.startTrace("test");
|
||||
TraceTemplate traceTemplate = new TraceTemplate(this.tracer);
|
||||
|
||||
Trace traceFromCallback = whenTraceCallbackReturningCurrentTraceIsExecuted(traceTemplate);
|
||||
Span spanFromCallback = whenTraceCallbackReturningCurrentTraceIsExecuted(traceTemplate);
|
||||
|
||||
then(traceFromCallback).isNotNull();
|
||||
then(traceFromCallback.getSpan().getTraceId()).isEqualTo(initialTrace.getSpan().getTraceId());
|
||||
then(spanFromCallback).isNotNull();
|
||||
then(spanFromCallback.getTraceId()).isEqualTo(initialSpan.getTraceId());
|
||||
}
|
||||
|
||||
private Trace whenTraceCallbackReturningCurrentTraceIsExecuted(TraceTemplate traceTemplate) {
|
||||
return traceTemplate.trace(new TraceCallback<Trace>() {
|
||||
private Span whenTraceCallbackReturningCurrentTraceIsExecuted(TraceTemplate traceTemplate) {
|
||||
return traceTemplate.trace(new TraceCallback<Span>() {
|
||||
@Override
|
||||
public Trace doInTrace(Trace trace) {
|
||||
return TraceContextHolder.getCurrentTrace();
|
||||
public Span doInTrace(Span span) {
|
||||
return SpanContextHolder.getCurrentSpan();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class SampleMessagingApplication {
|
||||
private SampleRequestResponse transformer;
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.github.kristofa.brave.SpanCollector;
|
||||
public class SampleRibbonApplication {
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -94,7 +93,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Trace trace = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
new AlwaysSampler());
|
||||
int millis = random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
@@ -103,7 +102,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
|
||||
String s = this.restTemplate.getForObject("http://localhost:" + this.port
|
||||
+ "/call", String.class);
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
return "traced/" + s;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class SampleSleuthApplication {
|
||||
public static final String CLIENT_NAME = "testApp";
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,11 @@ package tools;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.net.URI;
|
||||
@@ -53,7 +56,7 @@ public class RequestSendingRunnable implements Runnable {
|
||||
|
||||
private RequestEntity requestWithTraceId(long traceId) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(Trace.TRACE_ID_NAME, Span.IdConverter.toHex(traceId));
|
||||
headers.add(Span.TRACE_ID_NAME, Span.toHex(traceId));
|
||||
URI uri = URI.create(url);
|
||||
RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, uri);
|
||||
log.info("Request [" + requestEntity + "] is ready");
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.WebIntegrationTest;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.SleuthSink;
|
||||
@@ -60,7 +59,7 @@ public class ZipkinStreamTests extends AbstractIntegrationTest {
|
||||
await().until(zipkinServerIsUp());
|
||||
|
||||
long traceId = new Random().nextLong();
|
||||
Span span = MilliSpan.builder().traceId(traceId).spanId(traceId).name("test")
|
||||
Span span = Span.builder().traceId(traceId).spanId(traceId).name("test")
|
||||
.build();
|
||||
span.tag(getRequiredBinaryAnnotationName(), "10131");
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -94,7 +93,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Trace trace = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
new AlwaysSampler());
|
||||
int millis = random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
@@ -103,7 +102,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
|
||||
String s = this.restTemplate.getForObject("http://localhost:" + this.port
|
||||
+ "/call", String.class);
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
return "traced/" + s;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class SampleZipkinApplication {
|
||||
public static final String CLIENT_NAME = "testApp";
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceAccessor;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -94,7 +93,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
Trace trace = this.tracer.startTrace("customTraceEndpoint",
|
||||
Span span = this.tracer.startTrace("customTraceEndpoint",
|
||||
new AlwaysSampler());
|
||||
int millis = random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
@@ -103,7 +102,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
|
||||
String s = this.restTemplate.getForObject("http://localhost:" + this.port
|
||||
+ "/call", String.class);
|
||||
this.tracer.close(trace);
|
||||
this.tracer.close(span);
|
||||
return "traced/" + s;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -61,7 +61,7 @@ public class SleuthStreamAutoConfiguration {
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
return MessageBuilder.fromMessage(message)
|
||||
.setHeader(Trace.NOT_SAMPLED_NAME, "").build();
|
||||
.setHeader(Span.NOT_SAMPLED_NAME, "").build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -27,7 +27,8 @@ import java.util.Collections;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ServerPropertiesHostLocatorTests {
|
||||
MilliSpan span = new MilliSpan(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true, "process");
|
||||
Span span = new Span(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
"process");
|
||||
|
||||
@Test
|
||||
public void portDefaultsTo8080() {
|
||||
|
||||
@@ -16,22 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
@@ -51,6 +42,12 @@ import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -78,30 +75,30 @@ public class StreamSpanListenerTests {
|
||||
|
||||
@Test
|
||||
public void acquireAndRelease() {
|
||||
Trace context = this.tracer.startTrace("foo");
|
||||
Span context = this.tracer.startTrace("foo");
|
||||
this.tracer.close(context);
|
||||
assertEquals(1, this.test.spans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rpcAnnotations() {
|
||||
Span parent = MilliSpan.builder().traceId(1L).name("parent").remote(true)
|
||||
Span parent = Span.builder().traceId(1L).name("parent").remote(true)
|
||||
.build();
|
||||
Trace context = this.tracer.joinTrace("child", parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context.getSpan()));
|
||||
Span context = this.tracer.joinTrace("child", parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context));
|
||||
this.application
|
||||
.publishEvent(new ServerReceivedEvent(this, parent, context.getSpan()));
|
||||
.publishEvent(new ServerReceivedEvent(this, parent, context));
|
||||
this.application
|
||||
.publishEvent(new ServerSentEvent(this, parent, context.getSpan()));
|
||||
this.application.publishEvent(new ClientReceivedEvent(this, context.getSpan()));
|
||||
.publishEvent(new ServerSentEvent(this, parent, context));
|
||||
this.application.publishEvent(new ClientReceivedEvent(this, context));
|
||||
this.tracer.close(context);
|
||||
assertEquals(2, this.test.spans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSpanName() {
|
||||
Trace context = this.tracer.startTrace(null, (Sampler) null);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context.getSpan()));
|
||||
Span context = this.tracer.startTrace(null, null);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context));
|
||||
this.tracer.close(context);
|
||||
assertEquals(1, this.test.spans.size());
|
||||
this.listener.poll();
|
||||
@@ -129,7 +126,7 @@ public class StreamSpanListenerTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.cloud.sleuth.zipkin.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
import org.springframework.cloud.sleuth.stream.Spans;
|
||||
@@ -36,7 +35,7 @@ public class SamplingZipkinSpanIteratorTests {
|
||||
|
||||
@Test
|
||||
public void skipsInputSpans() {
|
||||
Spans spans = new Spans(host, Arrays.asList(span("message/sleuth")));
|
||||
Spans spans = new Spans(host, Collections.singletonList(span("message/sleuth")));
|
||||
|
||||
Iterator<zipkin.Span> result = new SamplingZipkinSpanIterator(Sampler.create(1.0f), spans);
|
||||
|
||||
@@ -71,6 +70,7 @@ public class SamplingZipkinSpanIteratorTests {
|
||||
|
||||
Span span(String name) {
|
||||
Long id = new Random().nextLong();
|
||||
return new MilliSpan(1, 3, name, id, Collections.<Long>emptyList(), id, true, true, "process");
|
||||
return new Span(1, 3, name, id, Collections.<Long>emptyList(), id, true, true,
|
||||
"process");
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,14 @@ import zipkin.BinaryAnnotation;
|
||||
import zipkin.Endpoint;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.stream.Host;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ZipkinMessageListenerTests {
|
||||
MilliSpan span = new MilliSpan(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true, "process");
|
||||
Span span = new Span(1, 3, "name", 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
"process");
|
||||
Host host = new Host("myservice", "1.2.3.4", 8080);
|
||||
Endpoint endpoint = Endpoint.create("myservice", 1 << 24 | 2 << 16 | 3 << 8 | 4, 8080);
|
||||
|
||||
@@ -79,7 +80,7 @@ public class ZipkinMessageListenerTests {
|
||||
// TODO: "unknown" bc process id, documented as not nullable, is null in some tests.
|
||||
@Test
|
||||
public void nullProcessIdCoercesToUnknownServiceName() {
|
||||
MilliSpan noProcessId = MilliSpan.builder().traceId(1L).name("parent").remote(true).build();
|
||||
Span noProcessId = Span.builder().traceId(1L).name("parent").remote(true).build();
|
||||
|
||||
zipkin.Span result = ZipkinMessageListener.convert(noProcessId, host);
|
||||
|
||||
|
||||
@@ -16,23 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
|
||||
@@ -47,6 +37,13 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -72,7 +69,7 @@ public class ZipkinSpanListenerTests {
|
||||
this.test.spans.clear();
|
||||
}
|
||||
|
||||
Span parent = MilliSpan.builder().traceId(1L).name("parent").remote(true).build();
|
||||
Span parent = Span.builder().traceId(1L).name("parent").remote(true).build();
|
||||
|
||||
/** Sleuth timestamps are millisecond granularity while zipkin is microsecond. */
|
||||
@Test
|
||||
@@ -119,7 +116,7 @@ public class ZipkinSpanListenerTests {
|
||||
*/
|
||||
@Test
|
||||
public void spanWithoutAnnotationsLogsComponent() {
|
||||
Trace context = this.tracer.startTrace("foo");
|
||||
Span context = this.tracer.startTrace("foo");
|
||||
this.tracer.close(context);
|
||||
assertEquals(1, this.test.spans.size());
|
||||
assertThat(this.test.spans.get(0).binaryAnnotations.get(0).endpoint.serviceName)
|
||||
@@ -128,11 +125,11 @@ public class ZipkinSpanListenerTests {
|
||||
|
||||
@Test
|
||||
public void rpcAnnotations() {
|
||||
Trace context = this.tracer.joinTrace("child", parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context.getSpan()));
|
||||
this.application.publishEvent(new ServerReceivedEvent(this, parent, context.getSpan()));
|
||||
this.application.publishEvent(new ServerSentEvent(this, parent, context.getSpan()));
|
||||
this.application.publishEvent(new ClientReceivedEvent(this, context.getSpan()));
|
||||
Span context = this.tracer.joinTrace("child", parent);
|
||||
this.application.publishEvent(new ClientSentEvent(this, context));
|
||||
this.application.publishEvent(new ServerReceivedEvent(this, parent, context));
|
||||
this.application.publishEvent(new ServerSentEvent(this, parent, context));
|
||||
this.application.publishEvent(new ClientReceivedEvent(this, context));
|
||||
this.tracer.close(context);
|
||||
assertEquals(2, this.test.spans.size());
|
||||
}
|
||||
@@ -149,7 +146,7 @@ public class ZipkinSpanListenerTests {
|
||||
private List<zipkin.Span> spans = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler defaultSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user