Tracing và monitoring với OpenCensus

Toan Huynh
ZaloPay Engineering
10 min readAug 21, 2019

Giới thiệu

OpenCensus là một tập hợp các thư viện cho các ngôn ngữ khác nhau cho phép bạn thu thập các số liệu ứng dụng và traces trong môi trường phân tán, sau đó chuyển dữ liệu sang hệ thống backend của bạn chọn trong thời gian thực. Dữ liệu này có thể được phân tích bởi các nhà phát triển và quản trị viên để hiểu được tình trạng của ứng dụng và các vấn đề gỡ lỗi.

Hiện nay OpenCensus đã được merge chung với OpenTracing thành OpenTelemetry. Một phiên bản tổng hợp tất cả tính năng tốt nhất của OpenTracing và OpenCensus.

Tổng quan

OpenCensus cung cấp khả năng giám sát cho các microservicesmonoliths của bạn bằng cách tracing các yêu cầu khi chúng truyền qua các services và nắm bắt các số liệu quan trọng.

Chức năng chính của OpenCensus là khả năng thu thập trace và số liệu từ ứng dụng của bạn, hiển thị chúng cục bộ và gửi chúng đến bất kỳ công cụ phân tích nào (backend). Tuy nhiên, OpenCensus cung cấp nhiều hơn là chỉ thông tin chi tiết. Trang này mô tả một số chức năng đó và chỉ cho bạn các tài nguyên để xây dựng nó vào ứng dụng của bạn.

Sau khi kết hợp code của bạn với OpenCensus, bạn sẽ trang bị cho mình khả năng tối ưu hóa tốc độ dịch vụ, hiểu chính xác cách yêu cầu thông tin giữa các dịch vụ của bạn, thu thập bất kỳ số liệu hữu ích nào về toàn bộ kiến trúc của bạn và hơn thế nữa.

OpenCensus hỗ trợ cho nhiều ngôn ngữ lập trình như Go, Java, C#, Node.js, C++, Ruby, Erlang/Elixir, Python, Scala PHP.

Hỗ trợ backend bao gồm: Azure Monitor, Datadog, Instana, Jaeger, SignalFX, Stackdriver, Zipkin.

Tính năng

Thu thập dữ liệu trong hệ thống phân tán

OpenCensus nắm bắt và truyền các traces trong hệ thống phân tán qua hệ thống của bạn, cho phép bạn hình dung cách request của khách hàng truyền qua các dịch vụ, thực hiện nhanh chóng phân tích nguyên nhân sâu xa và phân tích độ trễ tốt hơn trên một tập hợp services. OpenCensus bao gồm các chức năng như truyền context và có thể tương tác với nhiều hệ thống theo dõi.

Thu thập dữ liệu Time-series

OpenCensus nắm bắt số liệu thống kê time-series quan trọng từ ứng dụng của bạn, bao gồm độ trễ, số lượng request và kích thước request cho mỗi endpoint. Sau khi được ghi lại, những thống kê riêng lẻ này có thể được tổng hợp thành các số liệu với các thời gian và kích thước bạn chọn.

Cung cấp API

OpenCensus cung cấp API cho tất cả các loại từ xa. Ví dụ: bạn có thể sử dụng những thứ này để xác định và nắm bắt các số liệu tùy chỉnh, thêm các khoảng hoặc chú thích bổ sung vào trace, xác định chính sách lấy mẫu theo dõi tùy chỉnh, chuyển đổi định dạng lan truyền context, v.v.

Context Propagation

Để tương quan các hoạt động và yêu cầu giữa các service với hành động ban đầu của khách hàng, context (thường ở dạng trace hoặc ID tương quan) phải được phổ biến trên toàn hệ thống của bạn. Việc thực hiện điều này tự động có thể khá khó khăn và việc thiếu lan truyền context tự động thường được xác định là điểm block lớn nhất đối với một tổ chức áp dụng theo dõi phân tán. OpenCensus cung cấp lan truyền context tự động trên các ngôn ngữ và frameworks của nó và cung cấp các API đơn giản để truyền thủ công hoặc thao tác context.

OpenCensus hỗ trợ một số định dạng lan truyền context khác nhau và là bản hiện thực của official W3C HTTP tracing header.

Dễ dàng tích hợp

OpenCensus có chứa một số lượng tích hợp đáng kinh ngạc. Điều này cho phép các trace và số liệu được thu thập từ các hệ thống RPC phổ biến, web frameworks và storage clients.

Cung cấp một bản hiện thực duy nhất cho mỗi ngôn ngữ lập trình

Mặc dù OpenCensus là một dự án nguồn mở với một cộng đồng cực kỳ tích cực, nó cũng được hưởng lợi từ việc duy trì một bản duy nhất cho mỗi ngôn ngữ. Điều này có nghĩa là các đóng góp được tập trung, rằng các nỗ lực không bị lãng phí cho nhiều triển khai cạnh tranh (đặc biệt quan trọng đối với tích hợp) và càng nhiều chức năng có sẵn càng tốt.

Chi phí thực hiện thấp

OpenCensus được sử dụng trong sản xuất tại một số công ty lớn nhất trên thế giới, và do đó, nó cố gắng để có một tác động hiệu suất nhỏ nhất có thể.

Tracing

Span

Span đại diện cho một hoạt động trong một trace. Span có thể là đại diện cho một request HTTP, một RPC, truy vấn cơ sở dữ liệu hoặc thậm chí là đường dẫn mà mã lấy trong mã người dùng, v.v.

Ví dụ:

Ở trên, bạn có thể thấy một trace với các spam khác nhau. Để trả lời /messages, một số yêu cầu nội bộ khác được thực hiện. Đầu tiên, chúng tôi kiểm tra xem người dùng có được xác thực hay không. Tiếp theo chúng tôi kiểm tra xem tin nhắn của họ có được lưu trữ không. Vì tin nhắn của họ không được lưu trong bộ nhớ cache, sau đó chúng tôi lấy nội dung của họ từ MySQL, lưu vào bộ đệm và sau đó cung cấp phản hồi có chứa tin nhắn của họ.

Một span bao gồm các field sau: Name, SpanID, TraceID, ParentID, StartTime/EndTime, Status, Time events, Link, SpanKind, TracesOption, Tracestate.

Name

Name span là một chuỗi mô tả về những gì span làm. Name Span nên có ý nghĩa thống kê. Hầu hết các công cụ phân tích và phụ trợ theo dõi sử Name tên span để tự động tạo báo cáo cho công việc được đại diện.

Ví dụ:

- “cache.Get” Bộ dữ liệu đại diện cho phương thức Get của cache service.
- “/messages” đại diện cho các trang web tin nhắn.
- ”/api/user/(\d+)” đại diện cho các trang chi tiết người dùng.
Names thường được tạo trong hàm khỏi tạo span

SpanID

SpanID là mã định dxanh duy nhất của span. Bao gồm 8 byte được tạo ngẫu nhiên.

TraceID

TraceID là định danh duy nhất cho một trace. Bao gồm 16 byte được tạo ngẫu nhiên.

ParentSpanID

  • ParentSpanID có thể NULL/empty hoặc là 1 spanID.
  • Span không có ParentSpanID được gọi là “Root span”.
  • Span với ParentSpanID được gọi là san con.
  • Nhiều span có thể có cùng ParentSpanID.
  • Một span chỉ có thể có ParentID.
  • Một child span cũng có thể là parent của một span mà nó sinh ra.

StartTime/EndTime

StartTime là thời gian lúc span bắt đầu.

EndTime là thời gian lúc span kết thúc.

Status

Status xác định error để biểu thị status có thể lọc của span tại một thời điểm.

Nó bao gồm một mã có kiểu int32 cũng như thông điệp mô tả.

Status cho phép theo dõi các công cụ trực quan để làm nổi bật các span không thành công và giúp khắc phục lỗi.

Time event

Bao gồm Annotation và Message events

  • Một Annotation kể một câu chuyện mô tả trong văn bản, về một sự kiện xảy ra trong suốt lifetime của span.
  • Một message event mô tả một message được gửi hoặc nhận giữa các span.

Link

Link mô tả mối quan hệ chéo giữa các span trong cùng một trace hoặc khác nhau. Ví dụ: nếu một hoạt động hàng loạt được thực hiện, bao gồm các trace khác nhau hoặc các quy trình khác nhau, link từ span này đến span khác có thể giúp tương quan các span liên quan.

SpanKind

SpanKind nêu chi tiết các mối quan hệ giữa các span ngoài mối quan hệ parent/child. SpanKind được liệt kê theo các giá trị sau:

TraceOptions

TraceOptions là một byte trên mỗi span.

Sampling

Trace data thường được thu thập với khối lượng lớn, nó không chỉ tốn kém để thu thập và lưu trữ mà còn tốn kém để truyền tải.

Sampling là quá trình đưa ra quyết định về việc có nên xử lý/ xuất bản một span hay không.

Samplers

OpenCensus cung cấp những loại Samnplers sau: Always, Never, Probabilistic, RateLimiting.

Global sampler

Global sampler là một sampler được thiết lập bơi global TraceConfig.

Per span sampler aka “Span scoped”. Sampler này được thiết lập khi bắt đầu một span, thông qua constructor.

Always sampler

Always sampler luôn trả về `True` cho mọi lần sampling.

Samplers.alwaysSample();

Never sample

Never sample luôn trả về `False` cho mọi lần sampling.

Samplers.neverSample();

Probabilistic

Probabilistic sampler trả về xác suất True hoặc Fasle cho việc sampled tùy thuộc vào kết quả của việc lật đồng xu.

Theo mặc định, tỷ lệ probabilistic sampling là 1 trên 10.000

Samplers.probabilitySampler(1/1000.0);

RateLimiting

RateLimiting sampler cố gắng lấy sample với a rate per time window, theo mặc định là 0,1 traces/giây. Khi áp dụng cho child Span của một sampled parent Span, child Span sẽ giữ quyết định sampling.

Stats/Metrics

Ứng dụng và request metrics là các chỉ số quan trọng về tính khả dụng. Custom metrics có thể cung cấp cái nhìn sâu sắc về cách các chỉ số khả dụng ảnh hưởng đến trải nghiệm người dùng hoặc doanh nghiệp. Dữ liệu được thu thập có thể giúp tự động tạo cảnh báo khi ngừng hoạt động hoặc kích hoạt các quyết định lập lịch tốt hơn để tăng quy mô triển khai tự động theo yêu cầu cao.

Stats collection cho phép người dùng thu thập các custom metrics và cung cấp một bộ các số liệu được xác định trước thông qua tích hợp framework. Dữ liệu được thu thập có thể là đa chiều và nó có thể được lọc và nhóm theo các tags.

Stats collection yêu cầu hai bước:

  • Định nghĩa các biện pháp và ghi lại các điểm dữ liệu.
  • Định nghĩa và đăng ký quan điểm để tổng hợp các giá trị được ghi lại.

Exporting

Dữ liệu được thu thập được tổng hợp và xuất sang các stats collection backends mà bạn chọn, bằng cách đăng ký một exporter.

Exporting mỗi measurement riêng lẻ sẽ rất tốn kém về băng thông mạng và chi phí CPU. Đây là lý do tại sao bộ sưu tập thống kê tổng hợp dữ liệu trong quy trình và chỉ exports dữ liệu tổng hợp.

Nhiều exporters có thể được đăng ký để tải dữ liệu lên nhiều backends khác nhau. Người dùng có thể hủy đăng ký các exporters nếu không còn cần thiết.

Measurement

Measurement là một điểm dữ liệu được tạo ra sau khi ghi một số lượng bằng measure. Một Measurement chỉ là một thống kê thô.

Ví dụ: đối với phép đo độ trễ (ms), 100 là measurement đại diện cho sự kiện độ trễ 100 ms.

Người dùng thu thập điểm dữ liệu về các biện pháp hiện có với bối cảnh hiện tại. Tags từ context hiện tại được ghi lại với các measurements nếu có.

Measure

Một measure đại diện cho một loại số liệu sẽ được ghi lại. Ví dụ: request latency in µs và request size in KBs là ví dụ về measures thu thập từ máy chủ.

Định nghĩa

Tất cả các measures được xác định bằng một tên và cũng có một mô tả và một đơn vị. Libraries và frameworks có thể xác định và export các measures cho người dùng cuối của họ để thu thập dữ liệu về các measures được cung cấp.

Loại measure

OpenCensus hiện tại cung cấp 2 loại measures: int64, float64

View

View là sự kết hợp của Aggregation được áp dụng cho Measure và Tags tùy chọn. View là kết nối với Metric exporters.

Aggregations

Các hàm Aggregations sau được hỗ trợ:

  • Count: Đếm số lượng điểm measurement.
  • Distribution: Phân phối biểu đồ của các điểm measurement.
  • Sum: Sum các điểm measurement.
  • LastValue: Giữ giá trị được ghi cuối cùng, loại bỏ mọi thứ khác.

Sampling

Stats KHÔNG sampled để có thể đại diện cho các trường hợp không phổ biến, do đó các số liệu thống kê LUÔN được ghi lại trừ khi xoá.

Lý do đằng sau điều này là các số liệu thống kê ngoại lệ như `99th latency event` hiếm khi xảy ra nhưng cũng không thể đoán trước được. Nếu hệ thống ghi của chúng tôi có low sampling, rất có thể chúng tôi sẽ bỏ lỡ việc ghi lại các sự kiện như vậy. Ngoài ra, không giống như spans, ghi lại các measurements chỉ yêu cầu cập nhật dữ liệu tổng hợp (xem dữ liệu) thay vì tạo các đối tượng mới, do đó, nó tương đối nhẹ — thậm chí luôn được sampled. Do đó đây là lý do tại sao các số liệu thống kê KHÔNG được lấy mẫu nhưng LUÔN LUÔN được ghi lại.

Ví dụ

Tracing

Maven Configuration

Cấu hình Exporter

Cấu hình Sampler

Tracer

Tạo span

Tạo child span

Shutdown Tracer

Thiết lập status cho span

Tạo một Annotation

Metrics

Maven Configuration

Tạo Measures cho Metrics

Tạo tags

Recording Metrics

Tổng kết

Với sự hỗ trợ tương thích cho hầu hết các ngôn ngữ và các hệ thống thu thập dữ liệu phổ biến, OpenCensus giúp dễ dàng trích xuất dữ liệu từ ứng dụng của bạn. Nếu bạn quan tâm đến việc tìm hiểu thêm hoặc tham gia vào công đồng OpenCensus, bạn có thể tham gia tại đây OpenCensus Community.

Tài liệu tham khảo

--

--