Platform Engineering 5 — Observability với OpenTelemetry

13 thg 7, 2026 3 lượt xem
#observability
#monitoring
#devops
#slo
#opentelemetry

Trong loạt Platform Engineering — Tổng quan, platform team cung cấp cho developer những golden path — con đường chuẩn, tự phục vụ, an toàn. Nếu IaC dựng hạ tầng, GitOps triển khai, và CI/CD biến code thành artifact, thì observability (khả năng quan sát) là năng lực trả lời câu hỏi: khi hệ thống chạy trong production, nó đang thực sự làm gì? Bài này nối tiếp Observability — Tổng quan nhưng nhìn từ góc platform: làm sao quan sát không còn là việc mỗi team tự chắp vá, mà là một platform capability cấp sẵn, chuẩn hóa quanh OpenTelemetry.

Monitoring không phải observability

Cần phân biệt hai khái niệm hay bị dùng lẫn. Monitoring là theo dõi những chỉ số ta đã biết trước cần theo dõi — CPU, RAM, số lỗi HTTP. Nó trả lời tốt câu hỏi "hệ thống có khỏe không" nhưng bó tay trước những sự cố chưa từng lường tới. Observability là đặc tính của hệ thống cho phép ta suy ra trạng thái bên trong từ dữ liệu nó phát ra, kể cả với những câu hỏi ta chưa nghĩ tới lúc thiết kế. Trong kiến trúc microservices và data pipeline nhiều tầng, một request có thể đi qua chục dịch vụ; khi chậm, ta cần đào được chính xác mắt xích nào nghẽn — đó là lúc monitoring truyền thống hụt hơi.

Ba trụ cột (và trụ thứ tư)

Observability hiện đại dựa trên ba loại tín hiệu (telemetry) bổ sung cho nhau. Mỗi loại giỏi trả lời một kiểu câu hỏi:

Trụ cộtBản chấtTrả lời câu hỏiĐặc điểm
MetricsSố đo tổng hợp theo thời gian (counter, gauge, histogram)Cái gì đang sai? Có sai không?Rẻ, gọn, tổng hợp; cảnh báo nhanh; mất chi tiết cá thể
LogsBản ghi sự kiện rời rạc, thường có cấu trúc (JSON)Tại sao sai? Chi tiết bối cảnhGiàu chi tiết; tốn lưu trữ; khó tổng hợp
TracesHành trình một request xuyên nhiều dịch vụ (span có cha-con)Ở đâu sai? Nghẽn ở tầng nào?Cho thấy quan hệ nhân quả và độ trễ từng chặng
  • Metrics như bảng đồng hồ xe: biết ngay tốc độ, nhiệt độ, còn xăng — phát hiện vấn đề. Ví dụ tỷ lệ lỗi API tăng vọt từ 0.1% lên 5%.
  • Logs như nhật ký hành trình: khi metrics báo động, đọc log để hiểu tại sao — "connection pool exhausted", stack trace, giá trị tham số bất thường.
  • Traces như bản đồ GPS ghi lại từng đoạn đường: một request thanh toán mất 3 giây — trace cho thấy 2.7 giây nằm ở lời gọi tới dịch vụ scoring, không phải ở database như ta tưởng.

Trụ cột thứ tư — profiles (continuous profiling) đang được chuẩn hóa: đo mức tiêu thụ CPU/bộ nhớ tới từng dòng code / hàm, trả lời "code nào ngốn tài nguyên". OpenTelemetry đã đưa profiling thành tín hiệu chính thức (signal) từ 2024.

Điểm mấu chốt: cần cả ba (bốn) vì mỗi loại trả lời một mảnh. Chỉ có metrics thì biết cháy nhà mà không biết phòng nào; chỉ có logs thì ngập trong chi tiết mà không thấy bức tranh lớn; chỉ có traces thì thấy đường đi mà thiếu bối cảnh nội tại. Giá trị thật đến từ tương quan (correlation): từ một điểm nhọn trên biểu đồ metric, nhảy sang đúng trace đang chậm, rồi từ span đó mở đúng các dòng log — nhờ chia sẻ chung trace_id.

OpenTelemetry — chuẩn mở hợp nhất

Trước OTel, mỗi loại tín hiệu và mỗi vendor có SDK riêng: bạn nhúng thư viện của Datadog để trace, Prometheus client để đo metric, một agent khác cho log. Đổi backend đồng nghĩa viết lại instrument. OpenTelemetry (OTel) — dự án CNCF hình thành từ hợp nhất OpenTracing và OpenCensus — giải bài toán này bằng cách chuẩn hóa cách sinh và truyền telemetry, tách rời khỏi nơi lưu và phân tích. Giai đoạn 2023–2025 OTel đã trở thành mặc định de-facto của ngành.

Các thành phần cốt lõi:

  • API & SDK đa ngôn ngữ: một bộ API thống nhất cho metrics, logs, traces (Go, Java, Python, .NET, JS, Rust...). Code chỉ phụ thuộc API trung lập; SDK lo phần export.
  • Semantic conventions: quy ước đặt tên thuộc tính chuẩn — http.request.method, db.system, service.name, messaging.system. Nhờ vậy dashboard và alert dùng được xuyên dịch vụ, xuyên ngôn ngữ mà không cần "phiên dịch".
  • Context propagation: truyền trace_id/span_id xuyên biên dịch vụ qua header (chuẩn W3C Trace Context: traceparent). Đây là thứ khâu các span rời rạc thành một trace hoàn chỉnh, kể cả khi request đi qua HTTP, gRPC hay Kafka.
  • OTel Collector: một tiến trình trung gian nhận → xử lý → xuất telemetry (chi tiết bên dưới).
  • OTLP: giao thức truyền chuẩn (OpenTelemetry Protocol) giữa SDK, Collector và backend.

Giá trị lớn nhất với platform team: tránh vendor lock-in. Instrument code một lần theo OTel; muốn đổi từ Jaeger sang Tempo, hay thêm một SaaS, chỉ sửa cấu hình Collector — không đụng code ứng dụng.

OTel Collector — trái tim đường ống

Collector là một binary duy nhất, cấu hình bằng YAML, gồm ba loại thành phần ghép thành pipeline:

  • Receivers: nhận dữ liệu vào — qua OTLP, hoặc scrape Prometheus, đọc log file, nhận Jaeger/Zipkin.
  • Processors: xử lý ở giữa — gom lô (batch) để giảm tải, lấy mẫu trace (tail_sampling), loại bỏ/che thông tin nhạy cảm (redact PII), thêm thuộc tính, giới hạn bộ nhớ.
  • Exporters: đẩy ra backend — Prometheus, Tempo, Loki, hoặc bất kỳ SaaS nào.

Đặt Collector giữa app và backend cho phép platform team quản lý tập trung: đổi backend, thêm sampling, che số tài khoản trong log — tất cả tại một chỗ, không cần đụng tới từng dịch vụ.

Backend và công cụ (ví dụ, trung lập)

OTel không ràng buộc backend. Một stack mã nguồn mở phổ biến:

  • Metrics: Prometheus (lưu time-series, truy vấn bằng PromQL) — xem PrometheusPromQL.
  • Traces: Jaeger hoặc Grafana Tempo.
  • Logs: Grafana Loki, hoặc ELK/OpenSearch (Elasticsearch + Logstash/Fluentd + Kibana).
  • Trực quan hóa: Grafana thống nhất cả ba trên một mặt kính, cho phép nhảy từ metric sang trace sang log — xem Grafana.

Hoặc dùng SaaS trọn gói (Datadog, Grafana Cloud, Honeycomb...). Vì đã chuẩn OTel, lựa chọn backend trở thành quyết định vận hành/chi phí chứ không khóa cứng kiến trúc.

SRE, SLO/SLI và cảnh báo theo triệu chứng

Có dữ liệu là một chuyện; biết khi nào cần báo động lại là chuyện khác. Triết lý SRE (Site Reliability Engineering) đưa ra khung định lượng độ tin cậy:

  • SLI (Service Level Indicator): một chỉ số đo đạc được về chất lượng dịch vụ. Ví dụ: tỷ lệ request thành công, độ trễ p95, độ tươi (freshness) của dữ liệu.
  • SLO (Service Level Objective): mục tiêu đặt ra cho SLI. Ví dụ: "99.9% request trả về dưới 300ms trong 30 ngày".
  • Error budget: phần "được phép hỏng" = 100% − SLO. SLO 99.9% cho ngân sách lỗi 0.1% — khoảng 43 phút downtime/tháng. Còn ngân sách thì đội được tự do release nhanh; cạn ngân sách thì đóng băng tính năng, dồn sức cho ổn định. Đây là công cụ ra quyết định, không chỉ để cảnh báo.

Cảnh báo theo triệu chứng (symptom-based) là nguyên tắc cốt lõi để tránh nhiễu: chỉ đánh thức người trực khi người dùng thực sự bị ảnh hưởng (SLO bị đe dọa), thay vì báo động mỗi khi một chỉ số nội tại (CPU 80%) vượt ngưỡng — CPU cao mà dịch vụ vẫn đáp ứng tốt thì không phải sự cố. Kỹ thuật nâng cao là burn-rate alerting: báo động khi tốc độ tiêu error budget quá nhanh, giúp phân biệt sự cố cấp bách với sụt giảm chậm. Xem thêm Alerting.

Hai phương pháp chọn chỉ số cần theo dõi:

  • RED (cho dịch vụ có request): Rate (số request/s), Errors (tỷ lệ lỗi), Duration (độ trễ). Hợp cho API.
  • USE (cho tài nguyên): Utilization (mức dùng), Saturation (độ bão hòa/hàng đợi), Errors. Hợp cho CPU, disk, connection pool.

Cả hai đều là biến thể của golden signals (latency, traffic, errors, saturation) — bộ tín hiệu tối thiểu Google khuyến nghị cho mọi dịch vụ.

Observability như một platform capability

Đây là điểm khác biệt của tư duy platform engineering. Nếu để mỗi đội tự lo quan sát, kết quả là: đội thì quên đo, đội thì đặt tên chỉ số lộn xộn, dashboard mỗi nơi một kiểu, alert ồn ào hoặc thiếu sót. Platform team biến observability thành golden path — mặc định có sẵn, đúng chuẩn, không cần nghĩ:

  • Auto-instrumentation: nhúng OTel qua nền tảng (sidecar, agent, hoặc thư viện chuẩn của template dịch vụ) để mỗi service tự động phát ra metrics/traces/logs mà dev không viết dòng nào. Ví dụ Java/Python có agent auto-instrument bám vào framework HTTP, DB client.
  • Dashboard chuẩn: mỗi service mới sinh ra kèm dashboard golden signals dựng sẵn (nhờ semantic conventions, template dùng chung được cho mọi service).
  • Alert chuẩn: bộ cảnh báo SLO mặc định, symptom-based, gắn đúng kênh trực.
  • SLO as code: khai báo SLO trong repo, tự sinh alert rule và error-budget dashboard.

Tất cả những thứ này thường được phơi bày qua Internal Developer Portal (ví dụ Backstage — xem plat-07): dev tạo service mới, chọn template, và observability "đến kèm trong hộp". Nhờ context propagation của OTel, trace tự nối liền xuyên các dịch vụ mà không cần thỏa thuận thủ công giữa các đội.

Observability cho dữ liệu (phân biệt ngắn)

Cần tách hai khái niệm dễ nhầm:

  • Observability của hệ thống dữ liệu (bài này): pipeline/job có chạy không, chạy nhanh không, nghẽn ở đâu — dùng chính metrics/logs/traces. Ví dụ: trace một job Spark xuyên các stage, đo độ trễ đọc/ghi.
  • Data observability (chất lượng dữ liệu): dữ liệu có đúng không — độ tươi (freshness), khối lượng (volume), phân phối (distribution), schema, tính đầy đủ. Đây là chủ đề của Data Quality, liên quan lineage và kiểm thử dữ liệu, khác về bản chất với quan sát hạ tầng.

Một platform trưởng thành phủ cả hai: biết job chạy được biết dữ liệu nó tạo ra là đáng tin.

Minh họa: cấu hình Collector và instrument một service

Ví dụ dưới đây chỉ để minh họa cấu trúc, không phải cấu hình production hoàn chỉnh.

Cấu hình OTel Collector (nhận OTLP, gom lô, che PII, xuất ba backend):

# otel-collector-config.yaml (minh họa)
receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }

processors:
  batch: { timeout: 5s }
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
  # Che số tài khoản trong thuộc tính trước khi xuất
  attributes/redact:
    actions:
      - key: account_no
        action: delete

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889          # metrics
  otlp/tempo:
    endpoint: tempo:4317            # traces
    tls: { insecure: true }
  loki:
    endpoint: http://loki:3100/otlp/v1/logs   # logs

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, attributes/redact, batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, attributes/redact, batch]
      exporters: [loki]

Instrument thủ công một service Python (tạo span có thuộc tính theo semantic convention):

# minh họa — OTel Python SDK
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource

resource = Resource.create({"service.name": "loan-scoring-api"})
provider = TracerProvider(resource=resource)
provider.add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True))
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)

def score_loan(app_id: str):
    with tracer.start_as_current_span("score_loan") as span:
        span.set_attribute("loan.application_id", app_id)
        result = call_model(app_id)          # span con tự nối nhờ context
        span.set_attribute("loan.decision", result.decision)
        return result

Với đa số dịch vụ, không cần viết tay như trên: auto-instrumentation (ví dụ opentelemetry-instrument python app.py) tự bọc các thư viện HTTP/DB/Kafka và phát trace ngay. Code thủ công chỉ dành cho các span nghiệp vụ đặc thù.

Use case thực tế

Bối cảnh NCB. Đội dữ liệu vận hành nhiều dịch vụ nội bộ ghép thành chuỗi: serving-layer (API tra cứu) → data-api (truy vấn kho) → feature-storescoring (chấm điểm tín dụng). Trước đây, khi API tra cứu chậm, mỗi đội chỉ nhìn được log của riêng mình; xác định mắt xích nghẽn phải họp và đối chiếu log thủ công, thường mất hàng giờ.

Triển khai. Platform team đưa OTel thành golden path:

  1. Auto-instrument cả bốn dịch vụ; mọi request mang một trace_id duy nhất truyền xuyên chuỗi qua header traceparent (W3C Trace Context).
  2. Dựng OTel Collector tập trung với processor attributes/redact xóa account_no, CMND/CCCD khỏi telemetry trước khi xuất — đáp ứng yêu cầu bảo vệ dữ liệu khách hàng, liên quan Access & Crypto.
  3. Xuất traces sang Tempo, metrics sang Prometheus, logs sang Loki; Grafana làm mặt kính chung.
  4. Đặt SLO cho API nội bộ: "99.5% request /customer/profile trả về dưới 400ms trong 30 ngày" → error budget ~0.5%.
  5. Alert theo error budget (burn-rate), symptom-based: chỉ báo động khi tốc độ tiêu ngân sách vượt ngưỡng, thay vì mỗi lần một pod CPU cao.

Kết quả (số liệu ước lượng, minh họa). Một sự cố chậm điển hình: trace cho thấy 2.1 trên 2.6 giây nằm ở một truy vấn thiếu index trong data-api — thấy ngay trên waterfall thay vì đoán mò. MTTR (thời gian trung bình khắc phục) giảm từ ~90 phút xuống ~25 phút (khoảng −70%). Số cảnh báo gửi đội trực giảm mạnh nhờ chuyển sang symptom-based, giảm mệt mỏi cảnh báo (alert fatigue). Dashboard golden signals cấp sẵn giúp một dịch vụ mới có quan sát đầy đủ ngay ngày đầu, thay vì mất vài ngày tự dựng.

Kết hợp với k8s production ops và tinh thần SRE, observability trở thành nền để đội dữ liệu ngân hàng cân bằng giữa tốc độ giao tính năng và độ tin cậy — đúng vai trò của một platform capability.

Ghi nhớ

  • Ba trụ cột bổ sung nhau: metrics (cái gì — có sai không), logs (tại sao — bối cảnh), traces (ở đâu — nghẽn tầng nào); thêm profiles (code nào ngốn tài nguyên). Giá trị đến từ tương quan qua trace_id chung, không phải từng loại rời rạc.
  • Monitoring ≠ observability: monitoring theo dõi thứ đã biết trước; observability cho phép hỏi cả những câu chưa lường tới.
  • OpenTelemetry là chuẩn mở de-facto (2023–2025): API/SDK trung lập + semantic conventions + context propagation + Collector + OTLP. Instrument một lần, đổi backend chỉ sửa cấu hình Collector → tránh vendor lock-in.
  • OTel Collector = receive → process → export; đặt giữa app và backend để quản lý tập trung sampling, che PII, chọn backend.
  • SLO/SLI + error budget là công cụ ra quyết định (release nhanh hay đóng băng), không chỉ để cảnh báo. Alert symptom-based / burn-rate để giảm nhiễu; chọn chỉ số bằng RED (dịch vụ) hoặc USE (tài nguyên), tối thiểu là golden signals.
  • Observability là platform capability: auto-instrument, dashboard + alert golden signals cấp sẵn cho dev qua golden path / IDP — không để mỗi đội tự chắp vá.
  • Phân biệt observability của hệ thống dữ liệu (job chạy được/nhanh không) với data observability (dữ liệu có đúng không — freshness/volume/schema).

Nguồn tham khảo

Bài viết liên quan

Phân biệt Continuous Integration, Delivery và Deployment; giải phẫu một pipeline (trigger, stage, job, step, artifact) và các lớp kiểm thử xếp theo chi phí. Bài viết một workflow GitHub Actions hoàn chỉnh (build, test, Docker), so sánh với GitLab CI, quản lý secrets an toàn và chọn chiến lược release rolling/blue-green/canary kèm cách rollback.

13 thg 7, 2026 5

Bài mở đầu series Linux cho data engineer: vì sao mọi hạ tầng dữ liệu đều chạy Linux, triết lý Unix, phân biệt terminal/shell/kernel, cấu trúc một lệnh, chuẩn thư mục FHS và cách đăng nhập server qua SSH.

13 thg 7, 2026 4

Bản đồ Kubernetes: control plane (API server, etcd, scheduler, controller manager), node (kubelet, kube-proxy, container runtime), mô hình khai báo & vòng điều khiển (reconciliation), và cách một Pod được tạo ra.

13 thg 7, 2026 4

Lập lịch job trích xuất dữ liệu trên Linux: cú pháp cron 5 trường, crontab, /etc/cron.d, MAILTO, khoá chống chồng job bằng flock; job một lần với at; systemd service & timer (OnCalendar, Persistent) như thay thế cron hiện đại, journalctl và logrotate. Bài mổ xẻ vì sao script chạy tay OK mà cron fail — sự khác biệt login/non-login shell và biến môi trường — cùng cách quản lý package (apt/yum/dnf) và so sánh cron vs systemd timer vs Airflow.

13 thg 7, 2026 4

Cảm nhận của bạn

Bình luận

Bạn cần để viết bình luận.

Chưa có bình luận. Hãy là người đầu tiên chia sẻ!