Trong phần này chúng ta sẽ setup Otel Collector để thu thập các traces và trực quan hóa bằng Zipkin và Grafana nha.
Đầu tiên chúng ta sẽ dựng con Otel Collector và Zipkin lên trước. Các bạn có thể clone con Otel Collector tại đây để tiến hành dựng lên ở local nhé!
Sau khi clone về các bạn mở file config lên xem thử nha, file có tên là otel-collector-config-demo.yml:
receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 exporters: # prometheus: # endpoint: "0.0.0.0:8889" # namespace: promexample # const_labels: # label1: value1 logging: loglevel: debug zipkin: endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" format: proto processors: batch: extensions: health_check: pprof: endpoint: :1888 zpages: endpoint: :55679 service: extensions: [pprof, zpages, health_check] pipelines: traces: receivers: [otlp] processors: [batch] exporters: [logging, zipkin] metrics: receivers: [otlp] processors: [batch] exporters: [logging]
Mình nói một chút về file cấu hình này nha:
-
receivers ở đây mình đặt là otlp và protocols là grpc và http, mặc định khi chúng ta lấy traces thông qua collector thì exporter theo hãng sẽ là otlp, port thì ta sẽ có hai port mặc định cho mỗi giao thức là grpc:4317 và http:4318. Chúng ta cùng quay lại Dockerfile lúc đầu và thêm dòng COPY và 3 biến môi trường ENV này vào nha:
COPY otel/opentelemetry-javaagent.jar /app/otel-agent.jar ENV OTEL_SERVICE_NAME=spring-boot-application ENV OTEL_TRACES_EXPORTER=otlp ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://172.16.1.24:4318
Khi chúng ta thực hiện theo dõi để lấy traces, metrics hoặc logs bằng OpenTelemetry đều bắt buộc phải có file opentelemetry-javaagent.jar và ba biến môi trường bên trên export và app của mình. Luồng thực hiện là Collector sẽ lấy traces về theo địa chỉ ENDPOINT mà ta đã định sẵn (mặc định Collector không có giao diện nên ta phải dùng công cụ bên thứ ba), để đưa các traces, metrics cũng như logs lên để xem và phân tích, có thể sử dụng các công cụ như là Zipkin, Prometheus, Grafana, Jeager, …. Và ở đây mình dùng là Zipkin.
- OTEL_SERVICE_NAME là tên bạn đặt cho service của mình, bạn đặt tùy chỉnh nha. Ở đây mình đặt là spring-boot-application.
- Như đã nói bên trên thì OTEL_TRACES_EXPORTER mình sẽ đặt là otlp. Tuy nhiên vẫn còn một vài cách đặt khác như là logging, … Các bạn có thể tham khảo thêm tại trang doc của hãng nha.
- OTEL_EXPORTER_OTLP_ENDPOINT là điểm cuối nhận các traces từ app chúng ta gửi đến, tức là gửi đến con collector chúng ta dựng ở local. Mình sẽ thu traces qua giao thức http nên sẽ để port là 4318. Các bạn nhớ thay địa chỉ IP thành địa chỉ IP của máy mình nha.
-
Ở đây mình đã cấu hình sẵn Zipkin luôn để dựng cùng con Collector này luôn. Bạn cần chú ý cái nữa là endpoint của Zipkin:
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
Đây là endpoint mặc định của nhà sản xuất nha, port mặc định là 9411 luôn, mình sẽ không đổi.
-
Tiếp theo là services:
traces: receivers: [otlp] processors: [batch] exporters: [logging, zipkin]
receivers: [otlp]: Đây là phần mà hệ thống sẽ nhận các dữ liệu về theo dõi (traces), còn otlp một chuẩn giao thức để truyền dữ liệu giám sát, bao gồm logs, metrics và traces.
processors: [batch]: Đây là phần mà dữ liệu theo dõi sẽ được xử lý trước khi gửi đi. Bộ xử lý này sẽ gom các sự kiện lại thành từng lô (batch) để tối ưu hóa việc gửi dữ liệu, giúp giảm thiểu số lượng yêu cầu mạng và cải thiện hiệu suất tổng thể.
exporters: [logging, zipkin]: Đây là phần mà dữ liệu theo dõi sẽ được xuất ra ngoài sau khi đã được xử lý. logging sẽ ghi dữ liệu theo dõi vào log. Đây thường là cách để kiểm tra hoặc debug và sau đó sẽ gửi dữ liệu theo dõi đến Zipkin để phân tích và trực quan hóa.
Bạn chỉ cần chú ý các thông số cấu hình như thế là được. Mình không thu metrics nên ta không cần quan tâm nhé, các thông số còn lại thì theo mặc định thôi.
Trong file docker-compose.yml mình đã định sẵn các port cần thiết như Zipkin là 9411, … Chúng ta dựng con Colletor này lên bằng docker-compose trước:
docker compose up -d
Tiếp theo chúng ta qua lại project java, sau khi thêm dòng COPY và ba biến môi trường ENV vào Dockerfile thì chúng ta sẽ tải file opentelemetry-javaagent.jar. Tại thư mục của project bạn tạo một thư mục khác là otel và cd vào thư mục đó luôn và sử dụng lệnh sau để tải:
mkdir otel && cd otel
curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
Đây là lệnh tải của hãng, ở chỗ latest sẽ tải version mới nhất, bạn có thể thay bằng một version cụ thể nha.
Sau khi tất cả đã xong, chúng ta sẽ build lại image. Bạn down các container lúc đầu đi nhé:
docker compose down
Sau đó build image với tag là v2, build xong các bạn nhớ sửa tag trong file docker-compose.yml của project java thành v2 nha:
docker build -t java-spring:v2 .
Chạy lại project lên và xem kết quả thôi nào:
docker compose up -d
Truy cập vào http://localhost:8080 để xem app của chúng ta và http://localhost:9411 để vào trang lấy traces của Zipkin nha:
Vậy là app của chúng ta đã chạy lại ngon lành.
Zipkin cũng đã lên luôn, các bạn lúc đầu sẽ chưa có data của các traces đâu nha, cái này mình test trước nên có. Bây giờ chúng ta sẽ tiến hành đăng nhập app và thêm một account mới xem trước nha!
Bây giờ qua lại trang của Zipkin, nhấn vài lần vào nút RUN QUERY để load data các trace nha!
Lúc này data đã lên, mình vừa add user mới và data của traces cũng hiển thị thao tác chúng ta thực hiện. Giờ chỉnh sửa user thử nha!
Mình chỉnh thành thế này thử, sau đó qua Zipkin load lại:
Đã hiện lên data cho thấy ta vừa edit thông tin của một user. Chúng ta có thể nhấn vào SHOW của từng traces để xem các mốc thời gian và sử dụng cho phân tích theo nhu cầu của mình nha!
Phía bên phải còn có nhiều thông tin chi tiết khác, bạn có thể xem qua!
Vậy là quá trình dựng con Collector tại local và đưa các trace qua Zipkin để xem và phân tích đã thành công.
Tiếp theo mình sẽ hướng dẫn các bạn dựng một con Collector khác và đưa traces lên Grafana nha! Cũng giống như con Collector trước có tích hợp sẵn Zipkin thì con Collector này cũng tích hợp sẵn Grafana. Con này của chính hãng Grafana phát hành luôn nên người ta sẽ cấu hình sẵn cho mình, mình chỉ việc clone về và chạy lên thôi!
Đầu tiên ta sẽ clone con Collector này về trước đã nhé!
git clone https://github.com/grafana/tempo.git
Sau khi clone về xong chúng ta down con Collector Zipkin lúc nãy đi rồi mới chạy con này nha! Bởi vì chúng ta đều sử dụng port 4318 để lấy trace thì khi cả hai con Collector chạy cùng một lúc và cùng một port như thế thì sẽ dễ xảy ra xung đột nên ta down con đầu tiên xuống.
Để chạy con Collector có Grafana này ta sẽ làm như sau:
cd tempo/example/docker-compose/local
docker compose up -d
Sau khi đã chạy và kiểm tra bằng docker ps thấy đã thành công ta truy cập vào http://localhost:3001 để xem trang của Grafana:
Sau đó các bạn chọn Explore, chọn data để xem là Tempo:
Chọn Search, chọn service name là ${OTEL_SERVICE_NAME}, sau đó nhấn vào Run Query để load data của service name này nha! Các bạn thử xóa cái user lúc nãy mình mới edit xong qua Grafana nhấn Run Query để load lại data:
Data của traces đã load lên thành công. Chúng ta có thể nhấn vào từng traces để xem các mốc thời gian như Zipkin nha!
Chúng sẽ trông như thế này, chúng ta có thể dùng các số liệu này để phân tích theo nhu cầu cá nhân nhé!
Vậy là chúng ta đã thành công lấy các traces bằng Collector và gửi chúng đến Zipkin và Grafana để xem và phân tích rồi. Tuy nhiên cách này vẫn chưa đủ khả thi, nếu áp dụng thì sẽ chỉ áp dụng được cho ứng dụng chạy trên docker thôi. Vậy nếu ứng dụng chạy dưới local hoặc local chúng ta không có docker thì sao? Phần sau mình sẽ giải thích và demo hướng dẫn cho các bạn nhé!