Git Product home page Git Product logo

spring-cloud / spring-cloud-sleuth Goto Github PK

View Code? Open in Web Editor NEW
1.8K 133.0 779.0 87.76 MB

Distributed tracing for spring cloud

Home Page: https://spring.io/projects/spring-cloud-sleuth

License: Apache License 2.0

CSS 1.10% Java 95.24% Shell 0.05% HTML 0.09% JavaScript 3.12% Kotlin 0.39%
java spring spring-boot spring-cloud tracing zipkin microservices cloud-native spring-cloud-core distributed-tracing

spring-cloud-sleuth's Introduction

Build
Gitter

Spring Cloud Sleuth

!!!! IMPORTANT !!!!

Spring Cloud Sleuth’s last minor version is 3.1. You can check the 3.1.x branch for the latest commits.

Warning
Spring Cloud Sleuth will not work with Spring Boot 3.x onward. The last major version of Spring Boot that Sleuth will support is 2.x.

The core of this project got moved to Micrometer Tracing project and the instrumentations will be moved to Micrometer and all respective projects (no longer all instrumentations will be done in a single repository.

You can check the Micrometer Tracing migration guide to learn how to migrate from Spring Cloud Sleuth to Micrometer Tracing.

Introduction

Spring Cloud Sleuth provides Spring Boot auto-configuration for distributed tracing.

Sleuth configures everything you need to get started. This includes where trace data (spans) are reported to, how many traces to keep (sampling), if remote fields (baggage) are sent, and which libraries are traced.

Quick Start

Add Spring Cloud Sleuth to the classpath of a Spring Boot application (together with a Tracer implementation) and you will see trace IDs in logs. Example of Sleuth with Brave tracer:

<!-- Spring Cloud Sleuth requires a Spring Cloud BOM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
            <version>${release.train.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- Boot's Web support -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Sleuth with Brave tracer implementation -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>
</dependencies>

Consider the following HTTP handler:

@RestController
public class DemoController {
    private static Logger log = LoggerFactory.getLogger(DemoController.class);

    @RequestMapping("/")
    public String home() {
        log.info("Handling home");
        return "Hello World";
    }
}

If you add that handler to a controller, you can see the calls to home() being traced in the logs (notice the 0b6aaf642574edd3 ids).

2020-10-21 12:01:16.285  INFO [,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] DemoController	          : Handling home!
Note
Instead of logging the request in the handler explicitly, you could set logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG.
Note
Set spring.application.name=myService (for instance) to see the service name as well as the trace and span IDs.

Documentation

Please visit the documentation page to read more about the project.

Building

Basic Compile and Test

To build the source you will need to install JDK 1.8.

Spring Cloud uses Maven for most build-related activities, and you should be able to get off the ground quite quickly by cloning the project you are interested in and typing

$ ./mvnw install
Note
You can also install Maven (>=3.3.3) yourself and run the mvn command in place of ./mvnw in the examples below. If you do that you also might need to add -P spring if your local Maven settings do not contain repository declarations for spring pre-release artifacts.
Note
Be aware that you might need to increase the amount of memory available to Maven by setting a MAVEN_OPTS environment variable with a value like -Xmx512m -XX:MaxPermSize=128m. We try to cover this in the .mvn configuration, so if you find you have to do it to make a build succeed, please raise a ticket to get the settings added to source control.

The projects that require middleware (i.e. Redis) for testing generally require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running.

Documentation

The spring-cloud-build module has a "docs" profile, and if you switch that on it will try to build asciidoc sources from src/main/asciidoc. As part of that process it will look for a README.adoc and process it by loading all the includes, but not parsing or rendering it, just copying it to ${main.basedir} (defaults to ${basedir}, i.e. the root of the project). If there are any changes in the README it will then show up after a Maven build as a modified file in the correct place. Just commit it and push the change.

Working with the code

If you don’t have an IDE preference we would recommend that you use Spring Tools Suite or Eclipse when working with the code. We use the m2eclipse eclipse plugin for maven support. Other IDEs and tools should also work without issue as long as they use Maven 3.3.3 or better.

Activate the Spring Maven profile

Spring Cloud projects require the 'spring' Maven profile to be activated to resolve the spring milestone and snapshot repositories. Use your preferred IDE to set this profile to be active, or you may experience build errors.

Importing into eclipse with m2eclipse

We recommend the m2eclipse eclipse plugin when working with eclipse. If you don’t already have m2eclipse installed it is available from the "eclipse marketplace".

Note
Older versions of m2e do not support Maven 3.3, so once the projects are imported into Eclipse you will also need to tell m2eclipse to use the right profile for the projects. If you see many different errors related to the POMs in the projects, check that you have an up to date installation. If you can’t upgrade m2e, add the "spring" profile to your settings.xml. Alternatively you can copy the repository settings from the "spring" profile of the parent pom into your settings.xml.

Importing into eclipse without m2eclipse

If you prefer not to use m2eclipse you can generate eclipse project metadata using the following command:

$ ./mvnw eclipse:eclipse

The generated eclipse projects can be imported by selecting import existing projects from the file menu.

Contributing

Spring Cloud is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master. If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.

Sign the Contributor License Agreement

Before we accept a non-trivial patch or pull request we will need you to sign the Contributor License Agreement. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.

Code of Conduct

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Code Conventions and Housekeeping

None of these is essential for a pull request, but they will all help. They can also be added after the original pull request but before a merge.

  • Use the Spring Framework code format conventions. If you use Eclipse you can import formatter settings using the eclipse-code-formatter.xml file from the Spring Cloud Build project. If using IntelliJ, you can use the Eclipse Code Formatter Plugin to import the same file.

  • Make sure all new .java files to have a simple Javadoc class comment with at least an @author tag identifying you, and preferably at least a paragraph on what the class is for.

  • Add the ASF license header comment to all new .java files (copy from existing files in the project)

  • Add yourself as an @author to the .java files that you modify substantially (more than cosmetic changes).

  • Add some Javadocs and, if you change the namespace, some XSD doc elements.

  • A few unit tests would help a lot as well — someone has to do it.

  • If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project).

  • When writing a commit message please follow these conventions, if you are fixing an existing issue please add Fixes gh-XXXX at the end of the commit message (where XXXX is the issue number).

Checkstyle

Spring Cloud Build comes with a set of checkstyle rules. You can find them in the spring-cloud-build-tools module. The most notable files under the module are:

spring-cloud-build-tools/
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml (3)
    └── main
        └── resources
            ├── checkstyle-header.txt (2)
            └── checkstyle.xml (1)
  1. Default Checkstyle rules

  2. File header setup

  3. Default suppression rules

Checkstyle configuration

Checkstyle rules are disabled by default. To add checkstyle to your project just define the following properties and plugins.

pom.xml
<properties>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> (1)
        <maven-checkstyle-plugin.failsOnViolation>true
        </maven-checkstyle-plugin.failsOnViolation> (2)
        <maven-checkstyle-plugin.includeTestSourceDirectory>true
        </maven-checkstyle-plugin.includeTestSourceDirectory> (3)
</properties>

<build>
        <plugins>
            <plugin> (4)
                <groupId>io.spring.javaformat</groupId>
                <artifactId>spring-javaformat-maven-plugin</artifactId>
            </plugin>
            <plugin> (5)
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>

    <reporting>
        <plugins>
            <plugin> (5)
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>
    </reporting>
</build>
  1. Fails the build upon Checkstyle errors

  2. Fails the build upon Checkstyle violations

  3. Checkstyle analyzes also the test sources

  4. Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules

  5. Add checkstyle plugin to your build and reporting phases

If you need to suppress some rules (e.g. line length needs to be longer), then it’s enough for you to define a file under ${project.root}/src/checkstyle/checkstyle-suppressions.xml with your suppressions. Example:

projectRoot/src/checkstyle/checkstyle-suppresions.xml
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
		"-//Puppy Crawl//DTD Suppressions 1.1//EN"
		"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
	<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
	<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
</suppressions>

It’s advisable to copy the ${spring-cloud-build.rootFolder}/.editorconfig and ${spring-cloud-build.rootFolder}/.springformat to your project. That way, some default formatting rules will be applied. You can do so by running this script:

$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/3.1.x/.editorconfig -o .editorconfig
$ touch .springformat

IDE setup

Intellij IDEA

In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin. The following files can be found in the Spring Cloud Build project.

spring-cloud-build-tools/
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml (3)
    └── main
        └── resources
            ├── checkstyle-header.txt (2)
            ├── checkstyle.xml (1)
            └── intellij
                ├── Intellij_Project_Defaults.xml (4)
                └── Intellij_Spring_Boot_Java_Conventions.xml (5)
  1. Default Checkstyle rules

  2. File header setup

  3. Default suppression rules

  4. Project defaults for Intellij that apply most of Checkstyle rules

  5. Project style conventions for Intellij that apply most of Checkstyle rules

Code style
Figure 1. Code style

Go to FileSettingsEditorCode style. There click on the icon next to the Scheme section. There, click on the Import Scheme value and pick the Intellij IDEA code style XML option. Import the spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml file.

Code style
Figure 2. Inspection profiles

Go to FileSettingsEditorInspections. There click on the icon next to the Profile section. There, click on the Import Profile and import the spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml file.

Checkstyle

To have Intellij work with Checkstyle, you have to install the Checkstyle plugin. It’s advisable to also install the Assertions2Assertj to automatically convert the JUnit assertions

Checkstyle

Go to FileSettingsOther settingsCheckstyle. There click on the + icon in the Configuration file section. There, you’ll have to define where the checkstyle rules should be picked from. In the image above, we’ve picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build’s GitHub repository (e.g. for the checkstyle.xml : https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/3.1.x/spring-cloud-build-tools/src/main/resources/checkstyle.xml). We need to provide the following variables:

Important
Remember to set the Scan Scope to All sources since we apply checkstyle rules for production and test sources.

Duplicate Finder

Spring Cloud Build brings along the basepom:duplicate-finder-maven-plugin, that enables flagging duplicate and conflicting classes and resources on the java classpath.

Duplicate Finder configuration

Duplicate finder is enabled by default and will run in the verify phase of your Maven build, but it will only take effect in your project if you add the duplicate-finder-maven-plugin to the build section of the projecst’s pom.xml.

pom.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

For other properties, we have set defaults as listed in the plugin documentation.

You can easily override them but setting the value of the selected property prefixed with duplicate-finder-maven-plugin. For example, set duplicate-finder-maven-plugin.skip to true in order to skip duplicates check in your build.

If you need to add ignoredClassPatterns or ignoredResourcePatterns to your setup, make sure to add them in the plugin configuration section of your project:

<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
            <configuration>
                <ignoredClassPatterns>
                    <ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
                    <ignoredClassPattern>.*module-info</ignoredClassPattern>
                </ignoredClassPatterns>
                <ignoredResourcePatterns>
                    <ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
                </ignoredResourcePatterns>
            </configuration>
        </plugin>
    </plugins>
</build>

spring-cloud-sleuth's People

Contributors

adriancole avatar asibross avatar atsharp avatar beatfreaker avatar chang-chao avatar dependabot-preview[bot] avatar dependabot[bot] avatar devinsba avatar flavium31 avatar gavlyukovskiy avatar hashzhang avatar jonatan-ivanov avatar kptfh avatar making avatar marcingrzejszczak avatar naveensrinivasan avatar olegdokuka avatar olegz avatar olgamaciaszek avatar reta avatar robotmrv avatar ryanjbaxter avatar shakuzen avatar simonbasle avatar smaldini avatar spencergibb avatar spring-builds avatar spring-operator avatar steve-oakey avatar tysewyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-cloud-sleuth's Issues

A question on implementation

Sorry to use your issue system in this way but I wanted to figure out something about your implementation.

I see you are using brave (https://github.com/openzipkin/brave) in some of your implementation. I am assuming that if I wanted to use Brave to connect to the zipkin running cluster to get the data saved to the collector by sleuth, that would a reasonable approach since the web ui presentation from zipkin is missing the data from my traces.

Use ThreadLocal.remove() to prevent memory leaks

Using ThreadLocal.set(null) to clear a value out causes a memory leak when ThreadPools are used. The problem is this:

  • ThreadLocal.set(null) will lookup a Map associated with the current Thread.
  • It sets the key of the map to this and a value of null

The Thread is then contained within a Thread pool that outlasts the application. So if the application is un-deployed, the reference to this remains within the Thread.

At first glance the problem may sound fairly minor. However, in many instances this is loaded by the child ClassLoader (i.e. the Web Application's ClassLoader). One example of how this happens is when using NamedThreadLocal.

The implication is that this.getClass().getClassLoader() will hold a reference to an un-deployed application's ClassLoader which refers to all the classes it loaded. This means there is a rather large leak within the application.

To avoid this, ThreadLocal.remove() should be used instead. The difference is that the Map entry is moved entirely vs mapping the key to a null value.

One example of the issue can be found in TraceContextHolder.currentSpan. There appear to be other places in Spring Cloud Sleuth that this should be fixed too.

Instrumentation for spring integration

Email thread as first thoughts.


Date: Tue, 4 Aug 2015 16:26:46 -0600
Subject: Tracing messages and spring integration
From: Spencer Gibb
To: Artem Bilan, Gary Russell

Artem and Gary,

I'm looking to add support to spring-cloud-sleuth for tracing (start/end timings, etc...) spring integration messages, especially those that cross thread boundaries.

Dave pointed me at the following:

https://jira.spring.io/browse/INT-2166
spring-projects/spring-integration#1493

Especially SecurityContextPropagationChannelInterceptor.java because it is similar to how the tracing context is held (ie a ThreadLocal).

Is this a good model to follow? If not, any other ideas?


Date: Tue, 4 Aug 2015 20:20:13 -0400
Subject: Re: Tracing messages and spring integration
From: Gary Russell
To: Spencer Gibb
Cc: Artem Bilan

Yes, we made it a subclass of for ThreadStatePropagationChannelInterceptor exactly that reason (propagating other thread-based state).

However, we don't currently have a solution for propagating across the network (which is a bit more tricky for security, we don't want to simply convey an Authentication - the sender might not be trusted).

If you need to propagate it across loosely coupled integration-based apps (e.g. via rabbitmq etc), it might be better to carry the trace information in a message header, similar to MessageHistory (when enabled in SI).

We added something similar to XD to convey XD module transits by adding to the header as the message transits each module in an XD stream.

Hope that helps.

Gary


Subject: Re: Tracing messages and spring integration
Date: Wed, 5 Aug 2015 09:22:58 +0100
To: Spencer Gibb

Yeah message headers sound like the best place to put the correlation ids. But the injection point (and how to automate it/ optimize it) might be similar. We just need a way to catch the incoming requests mainly.

add EnableAspectJAutoProxy(proxyTargetClass = true) be default

I have a project using Spring Boot 1.3.0.M5 and Spring Cloud Consul 1.0.0.M2. If I include a dependency to 1.0.0.M2 of Spring Cloud Sleuth in my POM I get the following exception when the webapp starts:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'cloudBusConsulInboundFlow' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consulInboundChannelAdapter' defined in class path resource [org/springframework/cloud/consul/bus/ConsulBusAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: @Scheduled method 'getEvents' found on bean target class 'ConsulInboundChannelAdapter' but not found in any interface(s) for a dynamic proxy. Either pull the method up to a declared interface or switch to subclass (CGLIB) proxies by setting proxy-target-class/proxyTargetClass to 'true'
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 18 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consulInboundChannelAdapter' defined in class path resource [org/springframework/cloud/consul/bus/ConsulBusAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: @Scheduled method 'getEvents' found on bean target class 'ConsulInboundChannelAdapter' but not found in any interface(s) for a dynamic proxy. Either pull the method up to a declared interface or switch to subclass (CGLIB) proxies by setting proxy-target-class/proxyTargetClass to 'true'
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at org.springframework.cloud.consul.bus.ConsulBusAutoConfiguration$$EnhancerBySpringCGLIB$$adbe3920.consulInboundChannelAdapter(<generated>)
    at org.springframework.cloud.consul.bus.ConsulBusAutoConfiguration.cloudBusConsulInboundFlow(ConsulBusAutoConfiguration.java:82)
    at org.springframework.cloud.consul.bus.ConsulBusAutoConfiguration$$EnhancerBySpringCGLIB$$adbe3920.CGLIB$cloudBusConsulInboundFlow$4(<generated>)
    at org.springframework.cloud.consul.bus.ConsulBusAutoConfiguration$$EnhancerBySpringCGLIB$$adbe3920$$FastClassBySpringCGLIB$$5faff540.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
    at org.springframework.cloud.consul.bus.ConsulBusAutoConfiguration$$EnhancerBySpringCGLIB$$adbe3920.cloudBusConsulInboundFlow(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 19 more
Caused by: java.lang.IllegalStateException: @Scheduled method 'getEvents' found on bean target class 'ConsulInboundChannelAdapter' but not found in any interface(s) for a dynamic proxy. Either pull the method up to a declared interface or switch to subclass (CGLIB) proxies by setting proxy-target-class/proxyTargetClass to 'true'
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:284)
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor$1.doWith(ScheduledAnnotationBeanPostProcessor.java:245)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:504)
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:240)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    ... 37 more

Any ideas why this happens?

Possible race condition with MDC

From a conversation with @rwinch

DefaultTrace is using ApplicationEventPublisher to publish events which setup the MDC

This can be problematic in many production applications I have dealt with because lots of people provide an async ApplicationEventMulticaster by defining SimpleApplicationEventMulticaster in their application context

This means there is a race condition in terms of what logs get the MDC setup and cleaned up

Also....

The bigger problem is since MDC will be setup on another thread...the MDC is not actually properly setup

because it is tied to the current thread (which will not be the Thread of execution)

Of course the second issue means that there really is no race condition, but it would be the case if the MDC from the original thread were passed in)

Traces for testsleuthapp are empty

I got zipkin up and running and ran this project.
As required I hit the localhost:3380 endpoint and saw hi/hi2 in the webpage

The output of the sleuth spring service is:

2015-07-30 17:04:48.789  INFO 35581 --- [trace=,span=] [nio-3380-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-07-30 17:04:48.789  INFO 35581 --- [trace=,span=] [nio-3380-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2015-07-30 17:04:48.827  INFO 35581 --- [trace=,span=] [nio-3380-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
2015-07-30 17:04:48.870  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=80dd38f4-6b54-4dfe-bae4-ef5b382787da] [nio-3380-exec-1] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Starting span: MilliSpan(begin=1438290288866, end=0, name=http/, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[], spanId=80dd38f4-6b54-4dfe-bae4-ef5b382787da, kVAnnotations={}, processId=null, timelineAnnotations=[])
2015-07-30 17:04:49.588  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=57efcb46-3130-402f-9347-30e6d4856431] [nio-3380-exec-2] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Starting span: MilliSpan(begin=1438290289587, end=0, name=http/hi2, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[80dd38f4-6b54-4dfe-bae4-ef5b382787da], spanId=57efcb46-3130-402f-9347-30e6d4856431, kVAnnotations={}, processId=null, timelineAnnotations=[])
2015-07-30 17:04:49.588  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=57efcb46-3130-402f-9347-30e6d4856431] [nio-3380-exec-2] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Starting parent: MilliSpan(begin=0, end=0, name=http/, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[], spanId=80dd38f4-6b54-4dfe-bae4-ef5b382787da, kVAnnotations={}, processId=null, timelineAnnotations=[TimelineAnnotation(time=1438290289588, msg=sr)])
2015-07-30 17:04:50.405  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=57efcb46-3130-402f-9347-30e6d4856431] [nio-3380-exec-2] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Stopped span: MilliSpan(begin=1438290289587, end=1438290290385, name=http/hi2, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[80dd38f4-6b54-4dfe-bae4-ef5b382787da], spanId=57efcb46-3130-402f-9347-30e6d4856431, kVAnnotations={random-sleep-millis=768}, processId=null, timelineAnnotations=[])
2015-07-30 17:04:50.405  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=57efcb46-3130-402f-9347-30e6d4856431] [nio-3380-exec-2] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Stopped parent: MilliSpan(begin=0, end=0, name=http/, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[], spanId=80dd38f4-6b54-4dfe-bae4-ef5b382787da, kVAnnotations={}, processId=null, timelineAnnotations=[TimelineAnnotation(time=1438290289588, msg=sr), TimelineAnnotation(time=1438290290388, msg=ss)])
2015-07-30 17:04:50.407  INFO 35581 --- [trace=bc842c62-9d44-4274-b339-658a81134372,span=80dd38f4-6b54-4dfe-bae4-ef5b382787da] [nio-3380-exec-1] o.s.c.sleuth.slf4j.Slf4jSpanListener     : Stopped span: MilliSpan(begin=1438290288866, end=1438290290399, name=http/, traceId=bc842c62-9d44-4274-b339-658a81134372, parents=[], spanId=80dd38f4-6b54-4dfe-bae4-ef5b382787da, kVAnnotations={}, processId=null, timelineAnnotations=[TimelineAnnotation(time=1438290289566, msg=cs), TimelineAnnotation(time=1438290289581, msg=cr)])

In terminal window where I ran ./bin/collector, I see the following logs

DEB [20150730-17:04:50.814] processor: Processing span: Span(8515628526714924549,http/,5675621177567114810,None,List(Annotation(1438290289588000,sr,Some(127.0.0.1:3380(testSleuthApp)),None), Annotation(1438290290388000,ss,Some(127.0.0.1:3380(testSleuthApp)),Some(800.milliseconds))),Vector(),false) from CgABdi2XBv4GrgULAAMAAAAFaHR0cC8KAAROw9tj6JJ2Og8ABgwAAAACCgABAAUcHg3LdyALAAIAAAACc3IMAAMIAAF/AAABBgACDTQLAAMAAAANdGVzdFNsZXV0aEFwcAAACgABAAUcHg3XrCALAAIAAAACc3MMAAMIAAF/AAABBgACDTQLAAMAAAANdGVzdFNsZXV0aEFwcAAIAAQADDUAAA8ACAwAAAAAAA==
log4j:WARN No appenders could be found for logger (com.zaxxer.hikari.HikariConfig).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
DEB [20150730-17:05:00.953] processor: Processing span: Span(8515628526714924549,http/hi2,-4693480670807411112,Some(5675621177567114810),List(),Vector(BinaryAnnotation(random-sleep-millis,java.nio.HeapByteBuffer[pos=0 lim=3 cap=3],AnnotationType(1,Bytes),Some(127.0.0.1:3380(testSleuthApp)))),false) from CgABdi2XBv4GrgULAAMAAAAIaHR0cC9oaTIKAAS+3WgycFy2WAoABU7D22PoknY6DwAGDAAAAAAPAAgMAAAAAQsAAQAAABNyYW5kb20tc2xlZXAtbWlsbGlzCwACAAAAAzc2OAgAAwAAAAEMAAQIAAF/AAABBgACDTQLAAMAAAANdGVzdFNsZXV0aEFwcAAAAA==
DEB [20150730-17:05:00.959] processor: Processing span: Span(8515628526714924549,http/,5675621177567114810,None,List(Annotation(1438290289566000,cs,Some(127.0.0.1:3380(testSleuthApp)),None), Annotation(1438290289581000,cr,Some(127.0.0.1:3380(testSleuthApp)),Some(15.milliseconds))),Vector(),false) from CgABdi2XBv4GrgULAAMAAAAFaHR0cC8KAAROw9tj6JJ2Og8ABgwAAAACCgABAAUcHg3LITALAAIAAAACY3MMAAMIAAF/AAABBgACDTQLAAMAAAANdGVzdFNsZXV0aEFwcAAACgABAAUcHg3LW8gLAAIAAAACY3IMAAMIAAF/AAABBgACDTQLAAMAAAANdGVzdFNsZXV0aEFwcAAIAAQAADqYAA8ACAwAAAAAAA==
> Building 98% > :zipkin-collector-service:run

Ok so when I go to localhost:8080 (not 8082 as in the instructions since there is nothing running at 8082) I see that the testsleuthapp is available form the drop down and that there is another drop down with all/http in it.

Selecting these and hitting Find Traces shows the following
Showing 0 of 0
Services:

I would have expected more. Any idea what is missing?

Support for non-webapps and/or non-actuator apps

Currently we try to determine the "endpoint" (in Zipkin terms but the code is in core) by looking at ServerProperties. What if there isn't one? Maybe the ApplicationContext id is a good enough replacement?

Log trace error using TraceCallable, TraceRunnable in ExecutorService

Hi,
I was testing ExecutorService for tracing using TraceCallable and TraceRunnable. It is throwing weird HTrace error log message when multiple TraceRunnable/TraceCallable are submitted the ExecutorService. After researching on it, I found that ThreadLocal variable to hold current span is never removed from that thread[worker thread]. If we are removing the current Span from worker thread [TraceContextHolder.removeCurrentSpan()]. It is working fine.

FYI, removeCurrentSpan() method from TraceContextHolder is only used in TraceFilter and TraceContextPropagationChannelInterceptor only.

Sleuth roadmap

I was wondering what the roadmap on this is. I am interested in using this to solve an architectural condition that I have in my system

Pare down what TraceFilter is logging

The primary use case of distributed tracing is latency analysis, so we probably can refine this quite a bit. Moreover, observability systems need to do least harm. Logging introduces overhead and storage burden that may impact the performance or usability of the system. This is why most distributed tracing systems log the least data required.

I don't think o.s.c.s.instrument.web.TraceFilter logs least data required: we literally log all headers. This includes useless data and data we should be careful with, such as cookies. For example, the accept-charset header alone is often a few times larger than a competing system's complete trace.

I suggest we invert the policy. Instead of logging the most data, log the least needed for analysis. Make things opt-in. This will get us far more mileage out of our storage systems, and make our instrumentation code do more with less cycles and memory.

Here are some examples of data minimalism in practice, in other tracing libraries.

Finagle

Finagle is behind twitter. Due to the volume of requests, they are very conservative with how much they trace. They only add the http method (as span name), and "http.uri" (stripped of parameters). Layers below do log other data, such as "srv/finagle.version", and "finagle.retry", but for http, only 2 things.

Brave

Brave does roughly the same thing as finagle, adding "http.responsecode".

Naver Pinpoint

Pinpoint logs library-specific events such as connect/disconnected, and up to several attributes. For example, they will record 64-512 characters of query parameters. Most clients will only record the URI and if cookie storage is set, the cookie.

Groupon

Groupon mentioned they cherry-pick a few fields for classification purposes (on root spans)

  • User agent
  • X-Forwarded-For info
  • Specialized data fields (browser identifying cookie, user identifying cookie)
  • Any A/B style experiment data they are bucketed into

TraceFilter's order should be configurable

In my app, I want to put TraceFilter before SecurityFilter. Currently the order for TraceFilter is hardcoded, I think it's better to provide a system property (and a default value) so that the order can be configured.

TraceWebFilter should not be ConditionalOnMissingBean

In org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration there is this part:

@Bean
    @ConditionalOnMissingBean
    public FilterRegistrationBean traceWebFilter(ApplicationEventPublisher publisher) {
        Pattern pattern = StringUtils.hasText(this.skipPattern) ? Pattern.compile(this.skipPattern)
                : TraceFilter.DEFAULT_SKIP_PATTERN;
        TraceFilter filter = new TraceFilter(this.trace, pattern);
        filter.setApplicationEventPublisher(publisher);
        return new FilterRegistrationBean(filter);
    }

The @ConditionalOnMissingBean is wrong since if you have at least one web filter this one won't be registered. IMO we should do @ConditionalOnProperty to choose whether you want it or not.

If you agree I'll file a PR (won't be really difficult ;) ).

WORKAROUND:

Just register the filter yourself:

 @Value("${spring.sleuth.instrument.web.skipPattern:}") String skipPattern;

    @Autowired Trace trace;

    @Bean
    public FilterRegistrationBean traceWebFilter(ApplicationEventPublisher publisher) {
        Pattern pattern = org.springframework.util.StringUtils.hasText(this.skipPattern) ? Pattern.compile(this.skipPattern)
                : TraceFilter.DEFAULT_SKIP_PATTERN;
        TraceFilter filter = new TraceFilter(this.trace, pattern);
        filter.setApplicationEventPublisher(publisher);
        return new FilterRegistrationBean(filter);
    }

MDC is cleared on all SpanStoppedEvents

MDC is cleared on all SpanStoppedEvents, but that can leave it empty if a span stops in the current thread but its parent is still active (e.g. hit the /call endpoint in the sample app and see what happens).

Compatibility with logback-spring.xml

With the latest version of Spring Boot you can use a logback-spring.xml file instead of added logging configuration in application.yml. I can't get get the trace or span IDs in to the logs though using the standard pattern elements:

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}] [%c] \(%t\) %msg%n
            </pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

Am I doing something wrong, or does Sleuth not support the logback-spring.xml file?

Limiting the output for Hystrix driven spans

I connected sleuth into one of my services and started the service and although the service just sits there with no requests coming through, I note that there is a lot of traffic related to I guess the Hystrix poller.

Is there a way to limit this? I am afraid that it will overwhelm my logs.

For example, this what I see ( a verifiable deluge)

2015-10-19 16:35:51.131  INFO 52084 --- [pool-7-thread-2] o.s.cloud.sleuth.log.Slf4jSpanListener   : Starting span: MilliSpan(begin=1445286951131, end=0, name=execution(HystrixStreamTask.gatherMetrics()), traceId=48628235-707e-4507-b261-654ae42d2888, parents=[], spanId=cdc96d57-353f-4bef-8196-b8fff6a6ea4b, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.131  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Continued span: MilliSpan(begin=1445286951131, end=0, name=execution(HystrixStreamTask.sendMetrics()), traceId=9d545c1d-c05e-4dbc-9bff-a1cc56572aa6, parents=[], spanId=589c03d2-da4c-4076-a0f6-96a982b656e0, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.131  INFO 52084 --- [pool-7-thread-2] o.s.cloud.sleuth.log.Slf4jSpanListener   : Continued span: MilliSpan(begin=1445286951131, end=0, name=execution(HystrixStreamTask.gatherMetrics()), traceId=48628235-707e-4507-b261-654ae42d2888, parents=[], spanId=cdc96d57-353f-4bef-8196-b8fff6a6ea4b, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.132  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Stopped span: MilliSpan(begin=1445286951131, end=1445286951132, name=execution(HystrixStreamTask.sendMetrics()), traceId=9d545c1d-c05e-4dbc-9bff-a1cc56572aa6, parents=[], spanId=589c03d2-da4c-4076-a0f6-96a982b656e0, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.132  INFO 52084 --- [pool-7-thread-2] o.s.cloud.sleuth.log.Slf4jSpanListener   : Stopped span: MilliSpan(begin=1445286951131, end=1445286951132, name=execution(HystrixStreamTask.gatherMetrics()), traceId=48628235-707e-4507-b261-654ae42d2888, parents=[], spanId=cdc96d57-353f-4bef-8196-b8fff6a6ea4b, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.630  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Starting span: MilliSpan(begin=1445286951630, end=0, name=execution(HystrixStreamTask.sendMetrics()), traceId=dc4ab46e-ad94-4154-92c6-95919eeb96e9, parents=[], spanId=97fba764-057e-4c16-a389-656d814310c2, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.631  INFO 52084 --- [pool-7-thread-5] o.s.cloud.sleuth.log.Slf4jSpanListener   : Starting span: MilliSpan(begin=1445286951630, end=0, name=execution(HystrixStreamTask.gatherMetrics()), traceId=d18b5427-896a-434d-9233-70f2ce305eec, parents=[], spanId=b458c814-0301-41f8-b90d-ca18d49cef10, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.631  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Continued span: MilliSpan(begin=1445286951630, end=0, name=execution(HystrixStreamTask.sendMetrics()), traceId=dc4ab46e-ad94-4154-92c6-95919eeb96e9, parents=[], spanId=97fba764-057e-4c16-a389-656d814310c2, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.631  INFO 52084 --- [pool-7-thread-5] o.s.cloud.sleuth.log.Slf4jSpanListener   : Continued span: MilliSpan(begin=1445286951630, end=0, name=execution(HystrixStreamTask.gatherMetrics()), traceId=d18b5427-896a-434d-9233-70f2ce305eec, parents=[], spanId=b458c814-0301-41f8-b90d-ca18d49cef10, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.631  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Stopped span: MilliSpan(begin=1445286951630, end=1445286951631, name=execution(HystrixStreamTask.sendMetrics()), traceId=dc4ab46e-ad94-4154-92c6-95919eeb96e9, parents=[], spanId=97fba764-057e-4c16-a389-656d814310c2, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:51.631  INFO 52084 --- [pool-7-thread-5] o.s.cloud.sleuth.log.Slf4jSpanListener   : Stopped span: MilliSpan(begin=1445286951630, end=1445286951631, name=execution(HystrixStreamTask.gatherMetrics()), traceId=d18b5427-896a-434d-9233-70f2ce305eec, parents=[], spanId=b458c814-0301-41f8-b90d-ca18d49cef10, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:52.131  INFO 52084 --- [pool-7-thread-3] o.s.cloud.sleuth.log.Slf4jSpanListener   : Starting span: MilliSpan(begin=1445286952131, end=0, name=execution(HystrixStreamTask.sendMetrics()), traceId=0ffcc619-c132-4f7a-a51c-e4a7a7ea968f, parents=[], spanId=98221b04-e193-4c1d-83bb-b62d90b0469e, remote=false, annotations={}, processId=null, timelineAnnotations=[])
2015-10-19 16:35:52.131  INFO 52084 --- [pool-7-thread-1] o.s.cloud.sleuth.log.Slf4jSpanListener   : Starting span: MilliSpan(begin=1445286952131, end=0, name=execution(HystrixStreamTask.gatherMetrics()), traceId=14e96c20-fe8f-4b5e-9b86-388b5ba8420c, parents=[], spanId=f4068893-bca2-415a-815a-0dd3ce3d5ff5, remote=false, annotations={}, processId=null, timelineAnnotations=[])

Smarter sampling and forcing tracing for certain requests

I have a question regarding how the tracing is turned on for requests:

I understand that on one hand there's the Sampler which allows for a service to basically turn on tracing for a random sample of requests (seems like the info part is not implemented yet in any way, correct?).
Then there is also the "X-Not-Sampled" header, which if set disables tracing for the call.
So basically sleuth allows for turning on tracing for a certain percentage of requests at any point, or disallowing the tracing of a call setting the X-Not-Sampled header.

Is there any way to force the tracing of a call setting a header e.g. if you want to debug a certain call?
In our experience logging all calls often creates too much information and using sampling proves most valuable at the most external entrypoints (so that we always get a full trace, instead of partial traces if some random sampler activates tracing somewhere downstream).
But it'd still be very useful to be able to turn on tracing to debug certain calls - so maybe having the same behavior of the X-B3-Sampled header in brave?
Also being able to trace certain calls, e.g. by rest method name with a different percentage would be very useful. I guess that the info part of the sampler is supposed to be used for this, but I can't see how this is going to work in the current implementation

I'm probably missing something on how this is working - if you have any more documentation/info on how these headers are being used please let me know!
Thanks in advance for your help!

mvn install -> Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (imports) on project spring-cloud-sleuth: Command execution failed

I'm sure I'm doing something silly here; but I just can't get this to compile.

▸ mvn -version
Apache Maven 3.0.5
Maven home: /usr/share/maven
Java version: 1.8.0_51, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-oracle/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.13.0-55-generic", arch: "amd64", family: "unix"

But get the following error:

▸ mvn install -s .settings.xml
[INFO] Scanning for projects...
Downloading: http://repo.spring.io/libs-snapshot-local/org/springframework/cloud/spring-cloud-build/1.1.0.BUILD-SNAPSHOT/maven-metadata.xml
Downloaded: http://repo.spring.io/libs-snapshot-local/org

...snip...

/workspaces/mrdavidlaing/src/spring-cloud-sleuth/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java:import com.google.common.base.Optional;
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Spring Cloud Sleuth ............................... FAILURE [6.179s]
[INFO] Spring Cloud Sleuth Core .......................... SKIPPED
[INFO] Spring Cloud Sleuth Zipkin ........................ SKIPPED
[INFO] Spring Cloud Sleuth Samples ....................... SKIPPED
[INFO] Spring Cloud Sleuth Sample ........................ SKIPPED
[INFO] spring-cloud-sleuth-sample-messaging .............. SKIPPED
[INFO] spring-cloud-sleuth-sample-ribbon ................. SKIPPED
[INFO] spring-cloud-sleuth-sample-zipkin ................. SKIPPED
[INFO] Spring Cloud Sleuth Docs .......................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.815s
[INFO] Finished at: Fri Aug 14 12:57:45 UTC 2015
[INFO] Final Memory: 15M/460M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (imports) on project spring-cloud-sleuth: Command execution failed. Process exited with an error: 0 (Exit value: 0) -> [Help 1]
[ERROR]

Support for configurable header names

The zipkin headers are here: http://zipkin.io/Instrumenting.html#instrumenting-other-libraries

Ids are encoded as hex strings
X-B3-TraceId: 64 encoded bits
X-B3-SpanId: 64 encoded bits
X-B3-ParentSpanId: 64 encoded bits
X-B3-Sampled: Boolean (either “1” or “0”)
X-B3-Flags: a Long

There is an obvious immediate problem: Sleuth uses UUID for the ids (64 bits is really too small and Zipkin admits it).

We could also support Zipkin headers as an enhancement (include both sets). Seems like a waste of headers (we only need 3, but we end up with 7 or 8).

Warnings in Hystrix threads

When running multiple requests in the logs we can find

bottling_1 | 2015-12-29 14:28:56.855  WARN 1 --- [trix-bottling-1] o.s.cloud.sleuth.util.ExceptionUtils     : Trace client warn: thread hystrix-bottling-1 tried to start a new Span with parent MilliSpan(begin=1451399336352, end=0, name=http/bottle, traceId=33eb5a7f-4ed1-4cfa-a86b-b0048a4aa801, parents=[c388bdf2-6696-4c2e-9262-57f5352ad184], spanId=79c65ba4-acb0-4455-a159-11a7a8409f5d, remote=false, exportable=true, annotations={/http/request/uri=http://172.17.0.12:9994/bottle, /http/request/endpoint=/bottle, /http/request/method=POST, /http/request/headers/x-span-id=c388bdf2-6696-4c2e-9262-57f5352ad184, /http/request/headers/x-span-name=calling_bottling, /http/request/headers/accept=text/plain, application/json, application/*+json, */*, /http/request/headers/test-communication-type=REST_TEMPLATE, /http/request/headers/x-parent-id=ef4d014f-4e53-4694-9e51-f3e7d6c216dd, /http/request/headers/process-id=33eb5a7f-4ed1-4cfa-a86b-b0048a4aa801, /http/request/headers/x-trace-id=33eb5a7f-4ed1-4cfa-a86b-b0048a4aa801, /http/request/headers/content-type=application/vnd.io.spring.cloud.bottling.v1+json, /http/request/headers/netflix.nfhttpclient.version=1.0, /http/request/headers/x-netflix-httpclientname=bottling, /http/request/headers/content-length=13, /http/request/headers/host=172.17.0.12:9994, /http/request/headers/connection=Keep-Alive, /http/request/headers/user-agent=Apache-HttpClient/4.5.1 (Java/1.8.0_66)}, processId=null, timelineAnnotations=[]), but there is already a currentSpan MilliSpan(begin=1451399336843, end=0, name=hystrix-bottling-1, traceId=33eb5a7f-4ed1-4cfa-a86b-b0048a4aa801, parents=[79c65ba4-acb0-4455-a159-11a7a8409f5d], spanId=75940851-0de6-4426-84a6-b443cf95bc66, remote=false, exportable=true, annotations={}, processId=null, timelineAnnotations=[])

Thrift exception - No name set in Span

Occasionally the following exception is present in the logs and the entry is not there in Zipkin

presenting_1 | 2015-12-31 08:26:24.780  WARN 1 --- [pool-7-thread-1] c.g.k.brave.scribe.ScribeClientProvider  : Thrift exception.
presenting_1 | 
presenting_1 | org.apache.thrift.TApplicationException: Internal error processing Log: 'com.twitter.zipkin.common.IncompleteTraceDataException: No name set in Span'
presenting_1 |  at org.apache.thrift.TApplicationException.read(TApplicationException.java:108) ~[libthrift-0.9.0.jar!/:0.9.0]
presenting_1 |  at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:71) ~[libthrift-0.9.0.jar!/:0.9.0]
presenting_1 |  at com.twitter.zipkin.gen.scribe$Client.recv_Log(scribe.java:74) ~[brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at com.twitter.zipkin.gen.scribe$Client.Log(scribe.java:61) ~[brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at com.github.kristofa.brave.scribe.SpanProcessingThread.log(SpanProcessingThread.java:120) [brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at com.github.kristofa.brave.scribe.SpanProcessingThread.log(SpanProcessingThread.java:110) [brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at com.github.kristofa.brave.scribe.SpanProcessingThread.call(SpanProcessingThread.java:96) [brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at com.github.kristofa.brave.scribe.SpanProcessingThread.call(SpanProcessingThread.java:36) [brave-spancollector-scribe-3.2.0.jar!/:na]
presenting_1 |  at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_66]
presenting_1 |  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
presenting_1 |  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
presenting_1 |  at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]

also there is another log

presenting_1 |  c.g.k.brave.scribe.SpanProcessingThread  : Logging spans failed (couldn't establish connection). 10 spans are lost!

The way Span is created is:

@RequestMapping(
            value = "/maturing",
            produces = PRESENTING_JSON_VERSION_1,
            consumes = PRESENTING_JSON_VERSION_1,
            method = PUT)
    public String maturing(@RequestHeader("PROCESS-ID") String processId) {
        log.info("new maturing with process [$processId]")
        Trace trace = traceManager.startSpan("inside_presenting_maturing_feed")
        try {
            return feedRepository.addModifyProcess(processId, ProcessState.MATURING)
        } finally {
            traceManager.close(trace);
        }
    }

Custom AsyncConfigurer not getting processed by AsyncCustomAutoConfiguration's BeanPostProcessor

I'm attempting to provide a custom AsyncConfigurer in my Boot application like this:

@Bean
    public AsyncConfigurer asyncConfigurer() {
        return new AsyncConfigurer() {
            @Override public Executor getAsyncExecutor() {
                ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
                taskExecutor.setCorePoolSize(5);
                taskExecutor.setMaxPoolSize(10);
                taskExecutor.setQueueCapacity(25);
                taskExecutor.setThreadNamePrefix("ThreadPoolTaskExecutor-");
                taskExecutor.initialize();
                return taskExecutor;
            }

            @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
                return new SimpleAsyncUncaughtExceptionHandler();
            }
        };
    }

As I read the AsyncCustomAutoConfiguration class, this should be detected and wrapped by the LazyTraceAsyncCustomizer. However, my bean is never post processed. In the logs, I've noticed this:

2015-11-25 15:48:18.128 [trace=,span=]  INFO 68413 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'demoSleuthApplication' of type [class com.example.DemoSleuthApplication$$EnhancerBySpringCGLIB$$fa790465] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-11-25 15:48:18.149 [trace=,span=]  INFO 68413 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'asyncConfigurer' of type [class com.example.DemoSleuthApplication$1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2

I've made various attempts to get this working including moving this Bean to its own Configuration class and nothing seems to work. Am I making invalid assumptions about the AsyncCustomAutoConfiguration class or is there something specific that I'm missing in getting this custom Bean to take over?

Support for Zuul proxy

Ribbon seems to work with the RestTemplate (and maybe Feign as well since yesterday), but the Zuul proxy is not sending the trace headers.

Doubt for close() method of TraceScope class

I was seeing close() method of TraceScope class. In this method, current thread's span is replaced with other span(savedSpan). See line number 108. Why is this done this way?

Project name

Sleuth was kind of off the cuff. Maybe spring-cloud-trace?

Support for Hystrix in Zuul proxy

The Zuul proxy uses a custom Hystrix command, but isn't aware of the trace context, so unless hystrix.execution.isolation.strategy=SEMAPHORE it won't work right now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.