478 lines
15 KiB
Plaintext
478 lines
15 KiB
Plaintext
[[howto]]
|
|
= "`How-to`" Guides
|
|
|
|
include::_attributes.adoc[]
|
|
|
|
This section provides answers to some common "`how do I do that...?`" questions that often arise when using {project-full-name}.
|
|
Its coverage is not exhaustive, but it does cover quite a lot.
|
|
|
|
If you have a specific problem that we do not cover here, you might want to check out
|
|
https://stackoverflow.com/tags/{project-name}[stackoverflow.com] to see if someone has already provided an answer.
|
|
Stack Overflow is also a great place to ask new questions (please use the `{project-name}` tag).
|
|
|
|
We are also more than happy to extend this section.
|
|
If you want to add a "`how-to`", send us a {github-code}[pull request].
|
|
|
|
[[how-to-set-up-sleuth-with-brave]]
|
|
== How to Set Up Sleuth with Brave?
|
|
|
|
Add the Sleuth starter to the classpath.
|
|
|
|
====
|
|
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
|
.Maven
|
|
----
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>${release.train-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
|
.Gradle
|
|
----
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
|
|
}
|
|
----
|
|
====
|
|
|
|
[[how-to-set-up-sleuth-with-brave-zipkin-http]]
|
|
== How to Set Up Sleuth with Brave & Zipkin via HTTP?
|
|
|
|
Add the Sleuth starter and Zipkin to the classpath.
|
|
|
|
====
|
|
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
|
.Maven
|
|
----
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>${release.train-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
|
.Gradle
|
|
----
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
|
|
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
|
|
}
|
|
----
|
|
====
|
|
|
|
[[how-to-set-up-sleuth-with-brave-zipkin-messaging]]
|
|
== How to Set Up Sleuth with Brave & Zipkin via Messaging?
|
|
|
|
If you want to use RabbitMQ, Kafka or ActiveMQ instead of HTTP, add the `spring-rabbit`, `spring-kafka` or `org.apache.activemq:activemq-client` dependency.
|
|
The default destination name is `Zipkin`.
|
|
|
|
If using Kafka, you must add the Kafka dependency.
|
|
|
|
====
|
|
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
|
.Maven
|
|
----
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>${release.train-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.kafka</groupId>
|
|
<artifactId>spring-kafka</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
|
.Gradle
|
|
----
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
|
|
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
|
|
implementation "org.springframework.kafka:spring-kafka"
|
|
}
|
|
----
|
|
====
|
|
|
|
Also, you need to set the property `spring.zipkin.sender.type` property accordingly:
|
|
|
|
[source,yaml]
|
|
----
|
|
spring.zipkin.sender.type: kafka
|
|
----
|
|
|
|
If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `spring-rabbit` dependencies.
|
|
|
|
====
|
|
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
|
.Maven
|
|
----
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>${release.train-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.amqp</groupId>
|
|
<artifactId>spring-rabbit</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
|
.Gradle
|
|
----
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
|
|
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
|
|
implementation "org.springframework.amqp:spring-rabbit"
|
|
}
|
|
----
|
|
====
|
|
|
|
If you want Sleuth over ActiveMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies.
|
|
|
|
====
|
|
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
|
.Maven
|
|
----
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>${release.train-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.apache.activemq</groupId>
|
|
<artifactId>activemq-client</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
|
.Gradle
|
|
----
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
|
|
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
|
|
implementation "org.apache.activemq:activemq-client"
|
|
}
|
|
----
|
|
====
|
|
|
|
Also, you need to set the property `spring.zipkin.sender.type` property accordingly:
|
|
|
|
[source,yaml]
|
|
----
|
|
spring.zipkin.sender.type: activemq
|
|
----
|
|
|
|
[[how-to-see-spans-in-an-external-system]]
|
|
== How to See Spans in an External System?
|
|
|
|
If you can't see spans get reported to an external system (e.g. Zipkin), then it's most likely due to the following causes:
|
|
|
|
* <<not-sampled-span,Your span is not being sampled>>
|
|
* <<missing-dependency,You have forgotten to add the dependency to report to an external system (e.g. `spring-cloud-sleuth-zipkin`)>>
|
|
* <<connection-misconfiguration,You have misconfigured the connection to the external system>>
|
|
|
|
[[not-sampled-span]]
|
|
=== Your Span Is Not Being Sampled
|
|
|
|
In order to check if the span is not being sampled it's enough to see if the exportable flag is being set.
|
|
Let's look at the following example:
|
|
|
|
[indent=0]
|
|
----
|
|
2020-10-21 12:01:16.285 INFO [backend,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] Example : Hello world!
|
|
----
|
|
|
|
If the boolean value in the section `[backend,0b6aaf642574edd3,0b6aaf642574edd3,true]` is `true` means that the span is being sampled and should be reported.
|
|
|
|
[[missing-dependency]]
|
|
=== Missing Dependency
|
|
|
|
Up till Sleuth 3.0.0 the dependency `spring-cloud-starter-zipkin` included the `spring-cloud-starter-sleuth` dependency and the `spring-cloud-sleuth-zipkin` dependency.
|
|
With 3.0.0 `spring-cloud-starter-zipkin` was removed, so you need to change it to `spring-cloud-sleuth-zipkin`.
|
|
|
|
[[connection-misconfiguration]]
|
|
=== Connection Misconfiguration
|
|
|
|
Double check if the remote system address is correct (e.g. `spring.zipkin.baseUrl`) and that if trying to communicate over the broker, your broker connection is set up properly.
|
|
|
|
[[how-to-make-components-work]]
|
|
== How to Make RestTemplate, WebClient, etc. Work?
|
|
|
|
If you're observing that the tracing context is not being propagated then cause is one of the following:
|
|
|
|
* We are not instrumenting the given library
|
|
* We are instrumenting the library, however you misconfigured the setup
|
|
|
|
In case of lack of instrumentation capabilities please file https://github.com/spring-cloud/spring-cloud-sleuth/issues[an issue] with a request to add such instrumentation.
|
|
|
|
In case of the misconfiguration please ensure that the client you're using to communicate is a Spring bean.
|
|
If you create the client manually via the `new` operator the instrumentation will not work.
|
|
|
|
Example where instrumentation will work:
|
|
|
|
====
|
|
[source,java,indent=0]
|
|
----
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
@Configuration(proxyBeanMethods = false)
|
|
class MyConfiguration {
|
|
@Bean RestTemplate myRestTemplate() {
|
|
return new RestTemplate();
|
|
}
|
|
}
|
|
|
|
@Service
|
|
class MyService {
|
|
private final RestTemplate restTemplate;
|
|
|
|
MyService(RestTemplate restTemplate) {
|
|
this.restTemplate = restTemplate;
|
|
}
|
|
|
|
String makeACall() {
|
|
return this.restTemplate.getForObject("http://example.com", String.class);
|
|
}
|
|
|
|
}
|
|
|
|
----
|
|
====
|
|
|
|
Example where instrumentation will **NOT** work:
|
|
|
|
====
|
|
[source,java,indent=0]
|
|
----
|
|
@Service
|
|
class MyService {
|
|
|
|
String makeACall() {
|
|
// This will not work because RestTemplate is not a bean
|
|
return new RestTemplate().getForObject("http://example.com", String.class);
|
|
}
|
|
|
|
}
|
|
|
|
----
|
|
====
|
|
|
|
[[how-to-add-headers-to-the-http-server-response]]
|
|
== How to Add Headers to the HTTP Server Response?
|
|
|
|
Register a filter that will set the server response.
|
|
|
|
====
|
|
[source,java,indent=0]
|
|
----
|
|
import org.springframework.cloud.sleuth.Span;
|
|
import org.springframework.cloud.sleuth.Tracer;
|
|
|
|
import javax.servlet.Filter;
|
|
import org.springframework.web.server.WebFilter;
|
|
|
|
@Configuration(proxyBeanMethods = false)
|
|
class MyConfig {
|
|
|
|
// Example of a servlet Filter for non-reactive applications
|
|
@Bean
|
|
Filter traceIdInResponseFilter(Tracer tracer) {
|
|
return (request, response, chain) -> {
|
|
Span currentSpan = tracer.currentSpan();
|
|
if (currentSpan != null) {
|
|
HttpServletResponse resp = (HttpServletResponse) response;
|
|
// putting trace id value in [mytraceid] response header
|
|
resp.addHeader("mytraceid", currentSpan.context().traceId());
|
|
}
|
|
chain.doFilter(request, response);
|
|
};
|
|
}
|
|
|
|
// Example of a reactive WebFilter for reactive applications
|
|
@Bean
|
|
WebFilter traceIdInResponseFilter(Tracer tracer) {
|
|
return (exchange, chain) -> {
|
|
Span currentSpan = tracer.currentSpan();
|
|
if (currentSpan != null) {
|
|
// putting trace id value in [mytraceid] response header
|
|
exchange.getResponse().getHeaders().add("mytraceid", currentSpan.context().traceId());
|
|
}
|
|
return chain.filter(exchange);
|
|
};
|
|
}
|
|
}
|
|
|
|
----
|
|
====
|
|
|
|
IMPORTANT: Your spans need to be sampled for the parser to work. That means that you need to be able to export spans to e.g. Zipkin.
|
|
|
|
[[how-to-cutomize-http-client-spans]]
|
|
== How to Customize HTTP Client Spans?
|
|
|
|
Register a bean of `HttpRequestParser` type whose name is `HttpClientRequestParser.NAME` to add customization for the request side.
|
|
Register a bean of `HttpResponseParser` type whose name is `HttpClientRequestParser.NAME` to add customization for the response side.
|
|
|
|
====
|
|
[source,java,indent=0]
|
|
----
|
|
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/parser/WebClientCustomParserTests.java[tags=client_parser_config,indent=0]
|
|
----
|
|
====
|
|
|
|
[[how-to-cutomize-http-server-spans]]
|
|
== How to Customize HTTP Server Spans?
|
|
|
|
Register a bean of `HttpRequestParser` type whose name is `HttpServerRequestParser.NAME` to add customization for the request side.
|
|
Register a bean of `HttpResponseParser` type whose name is `HttpServerResponseParser.NAME` to add customization for the response side.
|
|
|
|
====
|
|
[source,java,indent=0]
|
|
----
|
|
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerParserTests.java[tags=server_parser_config,indent=0]
|
|
----
|
|
====
|
|
|
|
IMPORTANT: Your spans need to be sampled for the parser to work. That means that you need to be able to export spans to e.g. Zipkin.
|
|
|
|
[[how-to-see-application-name-in-logs]]
|
|
== How to See the Application Name in Logs?
|
|
|
|
Assuming that you haven't changed the default logging format set the `spring.application.name` property in `bootstrap.yml`, not in `application.yml`.
|
|
|
|
TIP: With the new Spring Cloud configuration bootstrap this should no longer be required since there will be no Bootstrap Context anymore.
|
|
|
|
[[how-to-change-context-propagation]]
|
|
== How to Change The Context Propagation Mechanism?
|
|
|
|
To use the provided defaults you can set the `spring.sleuth.propagation.type` property.
|
|
The value can be a list in which case you will propagate more tracing headers.
|
|
|
|
For Brave we support `AWS`, `B3`, `W3C` propagation types.
|
|
|
|
If you want to provide a custom propagation mechanism set the `spring.sleuth.propagation.type` property to `CUSTOM` and implement your own bean (`Propagation.Factory` for Brave).
|
|
Below you can find the examples:
|
|
|
|
====
|
|
[source,java,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
@Component
|
|
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java[tags=custom_propagator,indent=0]
|
|
----
|
|
====
|
|
|
|
[[how-to-implement-own-tracer]]
|
|
== How to Implement My Own Tracer?
|
|
|
|
Spring Cloud Sleuth API contains all necessary interfaces to be implemented by a tracer.
|
|
The project comes with OpenZipkin Brave implementation.
|
|
You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module.
|