Skywalking and Springboot integration

Vivek Singh
4 min readFeb 22, 2024

Git Link : https://github.com/Viveksingh1313/skywalking-springboot-poc

ReadMe file has been updated with all the details of how to run the application.

Screenshots from skywalking dashboard :

Theoretical concepts and code explanations

Components in Skywalking architecture :

Skywalking agent : An agent is a lightweight library which is embedded into the application you want to monitor. It collects telemetry data such as traces, metrics, and other performance related information from the application and sends the data to OAP collector.
We have a separate directory called skywalking-agent in the project which acts as the Java agent. You will have language specific agents based on your choice of language like Python, Go.

Skyalking OAP : OAP stands for Observability Analysis Platform. OAP server or collector is the core component of Skywalking backend. It will receive the data sent by Skywalking agent. It is responsible for data processing, aggregation, storage, and querying. It also provides APIs for querying the trace data.

In summary, the agent is responsible for collecting data from the application, while the OAP server is responsible for storing, processing, and serving this data for analysis and visualization purposes.

Skywalking DB : DB is used to store the data produced by your application using a skywalking agent. OAP server is responsbible to connect to the DB and perform all CRUD operations on DB.

Skywalking UI : The UI is a web-based interface for querying and visualizing data stored in Elasticsearch(using OAP server). You need to deploy the SkyWalking UI and configure it to connect to OAP server which then internally connects to ElasticSearch to make queries.

We use a docker-compose file to start OAP server, ElasticSearch DB, and Skywalking UI. (You will find the code inside docker-compose directory)


version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.4.2
container_name: elasticsearch
ports:
- "9200:9200"
healthcheck:
test: [ "CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1

oap:
image: apache/skywalking-oap-server:9.7.0
container_name: oap
depends_on:
elasticsearch:
condition: service_healthy
links:
- elasticsearch
ports:
- "11800:11800"
- "12800:12800"
healthcheck:
test: [ "CMD-SHELL", "/skywalking/bin/swctl ch" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
environment:
SW_STORAGE: elasticsearch
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
SW_HEALTH_CHECKER: default
SW_TELEMETRY: prometheus
JAVA_OPTS: "-Xms2048m -Xmx2048m"

ui:
image: apache/skywalking-ui:9.7.0
container_name: ui
depends_on:
oap:
condition: service_healthy
links:
- oap
ports:
- "8080:8080"
environment:
SW_OAP_ADDRESS: http://oap:12800
SW_ZIPKIN_ADDRESS: http://oap:9412

How does Skywalking create same traceId across all microservices for an endpoint call?

Quite simple and logical. Whenever you invoke any endpoint in your application, skywalking creates a traceId for the endpoint. This traceId is then attached to the headers, and as the endpoint traverses through your microservices, the traceId is retrieved from the headers and used for different purposes to collect the data.

Steps to start the application

1 ./docker-compose docker-compose -f skywalking.yml up

2. gradle :zull-gateway:bootRun
3. gradle :user-service:bootRun

As an addition step, you can import the postman collection provided in root folder to your postman application. After this hit the endpoint for skyalking to have data collected.

curl --location 'http://localhost:9080/demo/api/user' \
--header 'token: test' \
--header 'Content-Type: application/json' \
--data '{
"name": "test320"
}'

curl --location 'http://localhost:9080/demo/api/user' \
--header 'token: test'

If you don’t want to use postman, call above 2 endpoints multiple timses, for skywalking dashboard to show data.

Hit localhost:8080 to visualize data on skywalking UI

As of now this application works on Java 11/Java 17.

We are using 2 additional libraries of skywalking in this project:

 implementation 'org.apache.skywalking:apm-toolkit-trace:9.1.0'
implementation 'org.apache.skywalking:apm-toolkit-logback-1.x:9.1.0'

toolkit-trace : The @TraceCrossThread annotation in Apache SkyWalking is used to mark a method or function to be traced across different threads. In a distributed system, an operation may span multiple threads, especially in asynchronous or multi-threaded environments. When using SkyWalking for distributed tracing, it’s crucial to ensure that the entire operation, even if executed across multiple threads, is traced as a single logical unit. By annotating a method or function with @TraceCrossThread, you instruct SkyWalking to trace the execution of that method across different threads. This ensures that the entire operation is captured and correlated properly in the distributed trace. The entire operation will be traced against a unique specific spanId. There are more use cases in this library. This is just one.

apm-toolkit-logback : Designed for integrating SkyWalking’s distributed tracing capabilities with Logback, which is a logging framework for Java. With the library and configuration in place, your application’s logs will be automatically instrumented to include tracing information provided by SkyWalking. You will have to use appenders provided by skywalking in your logback.xml file(Please check this in github application provided).

Please feel free to reach out to me @vivek.sinless@gmail.com or connect me on LinkedIn

--

--

Vivek Singh

Software Developer. I write about Full Stack, NLP and Blockchain. Buy me a coffee - buymeacoffee.com/viveksinless