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