Spring Cloud Sleuth & Zipkin
Overview
Spring cloud sleuth is deprecated, Refer to https://gitorko.github.io/post/spring-observability/
Spring cloud sleuth helps you trace a request and zipkin server help you trace in a distributed environment.
Github: https://github.com/gitorko/project72
Spring Cloud Sleuth & Zipkin
How do you trace & debug a request in a single server? Now when it is deployed in pods and scaled how do you trace a request in a distributed environment? Spring Cloud Sleuth help you trace a request by appending unique trace id in the log statements. You can the publish such traces to the zipkin server which lets you visualize a request across distributed environment. You can then see the latency of each request in a distributed transaction.
Internally it has 4 modules –
- Collector – Once any component sends the trace data arrives to Zipkin collector daemon, it is validated, stored, and indexed for lookups by the Zipkin collector.
- Storage – This module store and index the lookup data in backend. Cassandra, ElasticSearch and MySQL are supported.
- Search – This module provides a simple JSON API for finding and retrieving traces stored in backend. The primary consumer of this API is the Web UI.
- Web UI – A very nice UI interface for viewing traces.
Code
1package com.demo.project72.service; 2 3import java.util.concurrent.TimeUnit; 4 5import brave.Span; 6import brave.Tracer; 7import lombok.RequiredArgsConstructor; 8import lombok.SneakyThrows; 9import lombok.extern.slf4j.Slf4j; 10import org.springframework.scheduling.annotation.Async; 11import org.springframework.scheduling.annotation.EnableAsync; 12import org.springframework.stereotype.Service; 13 14@Service 15@Slf4j 16@EnableAsync 17@RequiredArgsConstructor 18public class GreetService { 19 20 private final Tracer tracer; 21 22 @SneakyThrows 23 public void doSomeWorkSameSpan() { 24 TimeUnit.SECONDS.sleep(1); 25 log.info("Work Span"); 26 } 27 28 public void doSomeWorkNewSpan() throws InterruptedException { 29 log.info("Original span"); 30 Span newSpan = tracer.nextSpan().name("newSpan").start(); 31 try (Tracer.SpanInScope ws = tracer.withSpanInScope(newSpan.start())) { 32 TimeUnit.SECONDS.sleep(1); 33 log.info("New Span"); 34 } finally { 35 newSpan.finish(); 36 } 37 log.info("Original span"); 38 } 39 40 @Async 41 public void asyncMethod() throws InterruptedException { 42 log.info("Start Async Method"); 43 TimeUnit.SECONDS.sleep(1); 44 log.info("End Async Method"); 45 } 46} 1package com.demo.project72.config; 2 3import java.util.concurrent.Executor; 4 5import lombok.RequiredArgsConstructor; 6import org.springframework.beans.factory.BeanFactory; 7import org.springframework.cloud.sleuth.instrument.async.LazyTraceExecutor; 8import org.springframework.context.annotation.Configuration; 9import org.springframework.scheduling.annotation.AsyncConfigurer; 10import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 11 12@Configuration 13@RequiredArgsConstructor 14class ThreadConfig implements AsyncConfigurer { 15 16 private final BeanFactory beanFactory; 17 18 @Override 19 public Executor getAsyncExecutor() { 20 ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); 21 threadPoolTaskExecutor.setCorePoolSize(1); 22 threadPoolTaskExecutor.setMaxPoolSize(1); 23 threadPoolTaskExecutor.initialize(); 24 return new LazyTraceExecutor(beanFactory, threadPoolTaskExecutor); 25 } 26 27} 1spring: 2 main: 3 banner-mode: "off" 4 application: 5 name: project72 6 sleuth: 7 enabled: true 8 sampler: 9 probability: 1.0 10 zipkin: 11 base-url: http://localhost:9411/ 12 enabled: true 13 sender: 14 type: web 15 service: 16 name: my-service Setup
1# Project 72 2 3Spring Cloud Sleuth & Zipkin (Deprecated) 4 5[https://gitorko.github.io/spring-cloud-sleuth-zipkin/](https://gitorko.github.io/spring-cloud-sleuth-zipkin/) 6 7### Version 8 9Check version 10 11```bash 12$java --version 13openjdk 17.0.3 2022-04-19 LTS 14``` 15 16### Zipkin 17 18To run zipkin server use the docker command 19 20```bash 21docker run -d -p 9411:9411 --name my-zipkin openzipkin/zipkin 22docker stop my-zipkin 23docker start my-zipkin 24``` 25 26Login to zipkin UI, wait for few seconds for server to be up. 27 28[http://localhost:9411/zipkin/](http://localhost:9411/zipkin/) 29 30### Dev 31 32To run the code. 33 34```bash 35./gradlew clean build 36./gradlew bootRun 37``` Testing
Invoke the rest api and notice the trace
http://localhost:8080/hello-span
http://localhost:8080/hello-new-span
http://localhost:8080/hello-async
You can now view the trace in zipkin UI

