+1

Sử dụng OpenTelemetry để lấy Traces của ứng dụng Java backend (P2)

Trong bài viết này, ta sẽ setup Otel Collector để thu thập các traces và trực quan hóa các dữ liệu về traces thông qua Zipkin và Grafana.

Lấy traces thông qua Collector và Zipkin

Đầu tiên chúng ta sẽ dựng Otel Collector và trực quan hóa thông qua Zipkin trước bằng docker compose. Ta có thể clone Otel Collector tại đây và tiến hành dựng lên ở local.

Sau khi clone về ta mở file config lên xem, 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]

Sơ lượt về file config như sau:

  • receivers ở đây đặ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.

  • Ở đây đã cấu hình sẵn Zipkin để dựng cùng Collector. Cần chú ý 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, port mặc định là 9411, ta 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.

Vì chỉ lấy trace nên ta chỉ cần chú ý các thông số cấu hình như bên trên. Ta không thu metrics nên ta không cần quan tâm, các thông số còn lại thì theo mặc định.

Trong file docker-compose.yml đã định sẵn các port cần thiết như Zipkin là 9411, … Chúng ta sẽ dựng Colletor này lên bằng docker-compose trước:

docker compose up -d

Ta quay lại ở bài viết trước, ở Dockerfile ta thêm dòng COPY và 3 biến môi trường ENV này vào:

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 cơ chế và biến ENV tương tự) 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ào trong app của. Luồng thực hiện là app sẽ đẩy traces đến Collector 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, …

  • OTEL_SERVICE_NAME là tên đặt cho service app (tùy chỉnh).
  • 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, … Ta có thể tham khảo thêm tại trang doc của hãng.
  • 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 Collector chúng ta sẽ dựng ở local. Mình sẽ thu traces qua giao thức http nên sẽ để port là 4318 (Chú ý thay IP theo đúng IP local).

Sau khi đã thêm dòng COPY và ba biến môi trường ENV vào Dockerfile thì chúng ta sẽ cần tải file opentelemetry-javaagent.jar. Tại thư mục của project tạo một thư mục là otel và cd vào thư mục đó và sử dụng lệnh sau để tải:

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, ta có thể thay bằng một version cụ thể.

Sau khi tất cả đã xong, chúng ta sẽ build lại image. Tiến hành down các container lúc đầu đi:

docker compose down

Sau đó build image với tag là v2, build xong ta cần sửa tag trong file docker-compose.yml của project java thành v2 để chạy:

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 địa chỉ http://localhost:8081 để xem app của chúng ta và http://localhost:9411 để vào trang lấy traces của Zipkin:

App đã chạy lại thành công.

Zipkin đã khởi động (Zipkin chạy lần đầu sẽ không có data).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!

Bây giờ qua lại trang của Zipkin, nhấn vài lần vào nút RUN QUERY để load trace!

Lúc này data đã lên, ta 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!

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.

Phía bên phải còn có nhiều thông tin chi tiết khác, ta 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.

Lấy traces thông qua Collector và Grafana

Bây giờ ta dựng một con Collector khác và đưa traces lên Grafana. Cũng giống như Collector trước có tích hợp sẵn Zipkin thì Collector này cũng tích hợp sẵn Grafana. Collector này của chính hãng Grafana phát hành nên người ta sẽ cấu hình sẵn!

Đầu tiên ta sẽ clone con Collector này về.

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 đó 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! Ta 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.

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.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí