OpenTelemetry — Chuẩn Observability Mở Đang Thống Trị Hệ Thống Phân Tán

Posted on: 4/27/2026 1:11:58 PM

95% Tỷ lệ adopt cho cloud-native mới (2026)
12+ Ngôn ngữ lập trình hỗ trợ SDK
1.0 Declarative Config đạt Stable
v0.8 OBI (eBPF) Beta — KubeCon EU 2026

1. OpenTelemetry là gì và tại sao bạn cần quan tâm?

OpenTelemetry (OTel) là một dự án open-source thuộc CNCF (Cloud Native Computing Foundation), cung cấp bộ APIs, SDKs, và công cụ chuẩn hóa để thu thập dữ liệu telemetry — bao gồm traces, metrics, và logs — từ ứng dụng và hạ tầng phân tán.

Trước OTel, mỗi vendor observability (Datadog, New Relic, Dynatrace, Jaeger, Zipkin...) đều có agent và SDK riêng. Điều này tạo ra vendor lock-in nghiêm trọng: muốn đổi backend, bạn phải thay đổi code instrumentation trên toàn bộ service. OTel giải quyết bài toán này bằng cách tạo ra một lớp trung gian vendor-neutral — bạn instrument một lần, export đến bất kỳ backend nào qua giao thức OTLP (OpenTelemetry Protocol).

Tại sao 2026 là thời điểm vàng?

Tháng 4/2026 đánh dấu hai cột mốc lớn: Declarative Configuration chính thức stable (v1.0.0) và OBI (eBPF Instrumentation) ra mắt beta tại KubeCon EU. Cộng thêm .NET 10 với auto-instrumentation bản 1.15.0, OTel đã sẵn sàng cho production ở mọi ngôn ngữ chính.

2. Ba trụ cột: Traces, Metrics, Logs

OTel thống nhất ba loại tín hiệu (signals) quan trọng nhất trong observability:

graph LR
    subgraph Signals["Ba Trụ Cột OTel"]
        T["🔍 Traces
Theo dõi request
xuyên services"] M["📊 Metrics
Đo lường hiệu suất
theo thời gian"] L["📝 Logs
Sự kiện chi tiết
có ngữ cảnh"] end T -->|"trace_id"| C["Correlation
Engine"] M -->|"exemplar"| C L -->|"trace_id"| C C --> I["Insight
toàn diện"] style T fill:#e94560,stroke:#fff,color:#fff style M fill:#2c3e50,stroke:#fff,color:#fff style L fill:#4CAF50,stroke:#fff,color:#fff style C fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style I fill:#f8f9fa,stroke:#e94560,color:#2c3e50

Ba trụ cột observability của OpenTelemetry, liên kết qua trace_id

Traces (Distributed Tracing)

Một trace ghi lại hành trình hoàn chỉnh của một request khi nó di chuyển qua nhiều service. Mỗi trace chứa nhiều spans — mỗi span đại diện cho một đơn vị công việc (gọi API, truy vấn database, xử lý message queue...). Spans liên kết với nhau qua trace_idparent_span_id, tạo thành cây gọi (call tree).

Metrics

Metrics là dữ liệu số đo lường theo thời gian: request latency (histogram), error rate (counter), active connections (gauge), CPU usage... OTel hỗ trợ cả push (OTLP export) lẫn pull (Prometheus scrape) model.

Logs

OTel không thay thế logging framework hiện có (Serilog, NLog, log4j...) mà bổ sung context — inject trace_idspan_id vào mỗi log entry. Khi một request lỗi, bạn có thể nhảy thẳng từ trace sang log chi tiết mà không cần grep thủ công.

3. Kiến trúc tổng quan OpenTelemetry

graph TB
    subgraph Apps["Ứng dụng"]
        A1["Service A
.NET 10"] A2["Service B
Node.js"] A3["Service C
Go"] end subgraph SDK["OTel SDK / Auto-Instrumentation"] S1["SDK .NET"] S2["SDK JS"] S3["SDK Go"] end subgraph OBI_Layer["OBI (eBPF)"] OBI["Zero-Code
eBPF Probes"] end A1 --> S1 A2 --> S2 A3 --> S3 A1 -.->|"kernel hooks"| OBI A2 -.->|"kernel hooks"| OBI A3 -.->|"kernel hooks"| OBI S1 -->|"OTLP"| COL["OTel Collector"] S2 -->|"OTLP"| COL S3 -->|"OTLP"| COL OBI -->|"OTLP"| COL subgraph Backends["Backends"] J["Jaeger / Tempo"] P["Prometheus / Mimir"] L["Loki / Elasticsearch"] end COL --> J COL --> P COL --> L J --> G["Grafana Dashboard"] P --> G L --> G style A1 fill:#e94560,stroke:#fff,color:#fff style A2 fill:#2c3e50,stroke:#fff,color:#fff style A3 fill:#4CAF50,stroke:#fff,color:#fff style OBI fill:#ff9800,stroke:#fff,color:#fff style COL fill:#16213e,stroke:#fff,color:#fff style G fill:#e94560,stroke:#fff,color:#fff

Kiến trúc end-to-end: SDK + OBI → Collector → Backends → Visualization

Kiến trúc OTel gồm 4 tầng chính:

  • Instrumentation Layer: SDK tích hợp vào code (manual/auto) hoặc OBI hook ở kernel level
  • OTLP Protocol: Giao thức truyền tải chuẩn (gRPC hoặc HTTP/protobuf)
  • Collector: Nhận, xử lý (filter, enrich, batch), rồi export telemetry
  • Backend: Lưu trữ và truy vấn — Jaeger, Tempo, Prometheus, Loki, Elasticsearch...

4. Declarative Configuration — vừa đạt Stable

Tháng 4/2026, OpenTelemetry chính thức đánh dấu Declarative Configurationstable (v1.0.0). Đây là cách cấu hình OTel bằng file YAML thay vì hàng chục biến môi trường rời rạc.

Lợi ích chính

Một file YAML duy nhất thay thế hàng chục environment variables. Dễ version control, dễ review, dễ replicate giữa các môi trường.

Ví dụ cấu hình YAML

# otel-config.yaml — Declarative Configuration v1.0
file_format: "0.4"

tracer_provider:
  processors:
    - batch:
        schedule_delay: 5000
        export_timeout: 30000
        max_queue_size: 2048
        max_export_batch_size: 512
      exporter:
        otlp:
          protocol: grpc
          endpoint: http://otel-collector:4317
          compression: gzip

meter_provider:
  readers:
    - periodic:
        interval: 60000
        exporter:
          otlp:
            protocol: grpc
            endpoint: http://otel-collector:4317

logger_provider:
  processors:
    - batch:
        exporter:
          otlp:
            protocol: grpc
            endpoint: http://otel-collector:4317

resource:
  attributes:
    service.name: my-api
    service.version: "2.1.0"
    deployment.environment: production

Kích hoạt bằng biến môi trường duy nhất:

export OTEL_CONFIG_FILE=/etc/otel/otel-config.yaml

Các thành phần đã stable

Thành phần Mô tả Trạng thái
JSON Schema (opentelemetry-configuration) Data model schema version 1.0.0 ✅ Stable
YAML Representation File-based configuration format ✅ Stable
In-Memory Model SDK biểu diễn config trong bộ nhớ ✅ Stable
ConfigProperties Generic YAML mapping node ✅ Stable
PluginComponentProvider Cơ chế tham chiếu custom plugin ✅ Stable
OTEL_CONFIG_FILE Biến môi trường kích hoạt ✅ Stable

Hỗ trợ theo ngôn ngữ

Ngôn ngữ Trạng thái Declarative Config
Java✅ Đầy đủ (agent + SDK)
Go✅ Đầy đủ (Collector internal)
C++✅ Đầy đủ
JavaScript✅ Đầy đủ
PHP✅ Đầy đủ
.NET🔄 Đang phát triển
Python🔄 Đang phát triển

5. OBI: eBPF Instrumentation — Zero-Code Observability

OBI (OpenTelemetry eBPF Instrumentation) là bước nhảy vọt lớn nhất trong observability 2026. Kế thừa từ Grafana Beyla (được donate cho OTel cuối 2025), OBI sử dụng eBPF để hook trực tiếp vào kernel Linux — thu thập traces và metrics mà không cần sửa một dòng code nào.

graph TB
    subgraph KernelSpace["Kernel Space"]
        UP["uprobes
SSL_read/SSL_write"] KP["kprobes
tcp_sendmsg/recvmsg"] TP["tracepoints
scheduling, fs events"] end subgraph Maps["eBPF Maps"] PEA["perf_event_array"] RB["ring_buffer"] end subgraph UserSpace["User Space — OBI Agent (Go)"] MR["Map Reader"] SB["Span Builder"] FE["Filter & Enrich"] EX["OTLP Exporter"] end UP --> PEA KP --> PEA TP --> RB PEA --> MR RB --> MR MR --> SB SB --> FE FE --> EX EX -->|"gRPC/HTTP"| COL["OTel Collector"] style UP fill:#e94560,stroke:#fff,color:#fff style KP fill:#e94560,stroke:#fff,color:#fff style TP fill:#e94560,stroke:#fff,color:#fff style PEA fill:#2c3e50,stroke:#fff,color:#fff style RB fill:#2c3e50,stroke:#fff,color:#fff style EX fill:#4CAF50,stroke:#fff,color:#fff style COL fill:#16213e,stroke:#fff,color:#fff

Kiến trúc hai tầng của OBI: kernel probes → user-space agent → OTLP export

OBI hoạt động như thế nào?

OBI vận hành theo mô hình hai tầng:

  • Kernel Space: uprobes chặn SSL_read/SSL_write (đọc traffic TLS), kprobes theo dõi tcp_sendmsg/tcp_recvmsg, tracepoints ghi nhận scheduling và filesystem events
  • User Space: Agent Go đọc dữ liệu từ eBPF maps, xây dựng spans, áp dụng filter/enrichment, rồi export qua OTLP

Yêu cầu hệ thống

Yêu cầu Chi tiết
KernelLinux 5.8+ (RHEL/Rocky 4.18+ với backport); BTF bắt buộc
Kiến trúcamd64, arm64 (Graviton, Ampere)
Quyềnroot hoặc CAP_BPF + CAP_SYS_PTRACE
Pod confighostPID: true
Resources (typical)CPU: 100m–500m, Memory: 256Mi–512Mi

Giao thức hỗ trợ

Application Layer

HTTP/gRPC với automatic RED metrics, TLS-encrypted traffic (kernel-level SSL hooks), protocol-agnostic span generation

Database Protocols

PostgreSQL (pgx), MySQL, MongoDB, Redis, Couchbase — native server spans không cần ORM

Emerging (planned for 1.0)

GenAI APIs (OpenAI, Anthropic), Message brokers (MQTT, AMQP, NATS, Redis Pub/Sub)

SDK vs. OBI — Khi nào dùng gì?

Tiêu chí SDK (truyền thống) OBI (eBPF)
Thay đổi codeCần cho mỗi serviceKhông — kernel-level hooks
Third-party binariesKhông visibilityTự động visibility
Custom business events✅ Linh hoạt❌ Chỉ protocol-level
Payload accessApp-definedKernel-level SSL/DB capture
Deploy workflowRebuild + redeployConfig-driven, DaemonSet
Hệ điều hànhMọi OSChỉ Linux (kernel 5.8+)

Lưu ý quan trọng

OBI bổ sung chứ không thay thế SDK. Trong production, chạy song song cả hai: OBI cho infrastructure visibility tự động, SDK cho business-level events và custom spans.

6. Tích hợp OpenTelemetry trong .NET 10 / ASP.NET Core

.NET là một trong những ecosystem có hỗ trợ OTel tốt nhất nhờ System.Diagnostics — nền tảng native mà OTel .NET SDK xây dựng trên đó. Với auto-instrumentation v1.15.0 (tháng 4/2026), bạn có thể instrument một ASP.NET Core app trong vài phút.

Setup cơ bản

// Program.cs — .NET 10 + OpenTelemetry
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Metrics;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;

var builder = WebApplication.CreateBuilder(args);

// Resource: định danh service
var resource = ResourceBuilder.CreateDefault()
    .AddService("my-api", serviceVersion: "2.1.0");

// Traces
builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService("my-api"))
    .WithTracing(tracing => tracing
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddSqlClientInstrumentation(o => o.SetDbStatementForText = true)
        .AddRedisInstrumentation()
        .AddOtlpExporter(o =>
        {
            o.Endpoint = new Uri("http://otel-collector:4317");
            o.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
        }))
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddRuntimeInstrumentation()
        .AddOtlpExporter())
    .WithLogging(logging => logging
        .AddOtlpExporter());

var app = builder.Build();
app.MapControllers();
app.Run();

Auto-instrumentation không cần code

Nếu không muốn sửa Program.cs, sử dụng zero-code instrumentation qua environment variables:

# Dockerfile hoặc docker-compose.yml
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}
ENV CORECLR_PROFILER_PATH=/otel-dotnet/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
ENV DOTNET_ADDITIONAL_DEPS=/otel-dotnet/AdditionalDeps
ENV DOTNET_SHARED_STORE=/otel-dotnet/store
ENV OTEL_DOTNET_AUTO_HOME=/otel-dotnet
ENV OTEL_SERVICE_NAME=my-api
ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317

Custom spans cho business logic

using System.Diagnostics;

public class OrderService
{
    private static readonly ActivitySource Source = new("MyApp.OrderService");

    public async Task<Order> PlaceOrderAsync(OrderRequest request)
    {
        using var activity = Source.StartActivity("PlaceOrder");
        activity?.SetTag("order.customer_id", request.CustomerId);
        activity?.SetTag("order.items_count", request.Items.Count);

        var order = await _repository.CreateAsync(request);

        activity?.SetTag("order.id", order.Id);
        activity?.SetTag("order.total", order.Total);
        activity?.AddEvent(new ActivityEvent("OrderCreated"));

        return order;
    }
}

7. OpenTelemetry Collector — Trung tâm xử lý telemetry

OTel Collector là thành phần không thể thiếu trong production. Nó đóng vai trò gateway trung gian — nhận telemetry từ nhiều nguồn, xử lý (filter, transform, batch, sample), rồi export đến nhiều backends.

graph LR
    subgraph Receivers["Receivers"]
        R1["OTLP
(gRPC/HTTP)"] R2["Prometheus
scrape"] R3["Jaeger
thrift"] end subgraph Processors["Processors"] P1["Batch"] P2["Filter"] P3["Attributes
Enrich"] P4["Tail Sampling"] end subgraph Exporters["Exporters"] E1["OTLP → Tempo"] E2["Prometheus
Remote Write"] E3["Loki"] end R1 --> P1 R2 --> P1 R3 --> P1 P1 --> P2 P2 --> P3 P3 --> P4 P4 --> E1 P4 --> E2 P4 --> E3 style R1 fill:#e94560,stroke:#fff,color:#fff style R2 fill:#2c3e50,stroke:#fff,color:#fff style R3 fill:#4CAF50,stroke:#fff,color:#fff style P4 fill:#ff9800,stroke:#fff,color:#fff style E1 fill:#16213e,stroke:#fff,color:#fff style E2 fill:#16213e,stroke:#fff,color:#fff style E3 fill:#16213e,stroke:#fff,color:#fff

Pipeline Collector: Receivers → Processors → Exporters

Cấu hình Collector cho production

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    send_batch_size: 1024
    timeout: 5s

  filter:
    error_mode: ignore
    traces:
      span:
        - 'attributes["http.route"] == "/health"'
        - 'attributes["http.route"] == "/ready"'

  tail_sampling:
    decision_wait: 10s
    policies:
      - name: error-policy
        type: status_code
        status_code: {status_codes: [ERROR]}
      - name: latency-policy
        type: latency
        latency: {threshold_ms: 1000}
      - name: probabilistic-policy
        type: probabilistic
        probabilistic: {sampling_percentage: 10}

  resource:
    attributes:
      - key: deployment.environment
        value: production
        action: upsert

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

  prometheusremotewrite:
    endpoint: http://mimir:9009/api/v1/push

  loki:
    endpoint: http://loki:3100/loki/api/v1/push

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, filter, tail_sampling, resource]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [batch, resource]
      exporters: [prometheusremotewrite]
    logs:
      receivers: [otlp]
      processors: [batch, resource]
      exporters: [loki]

Tail Sampling — chiến lược tiết kiệm chi phí

Thay vì sample ngẫu nhiên ở SDK (head sampling), tail sampling tại Collector cho phép giữ 100% traces lỗi100% traces chậm (>1s), chỉ sample 10% traces bình thường. Giảm đáng kể chi phí storage mà không mất thông tin quan trọng.

8. Chiến lược triển khai Production-Grade

Deployment patterns

graph TB
    subgraph Pattern1["Pattern 1: Sidecar"]
        P1A["App Container"] --> P1C["Collector Sidecar"]
        P1C --> P1B["Backend"]
    end

    subgraph Pattern2["Pattern 2: DaemonSet"]
        P2A1["App Pod 1"] --> P2C["Collector
DaemonSet"] P2A2["App Pod 2"] --> P2C P2C --> P2B["Backend"] end subgraph Pattern3["Pattern 3: Gateway"] P3A["Collector
DaemonSet"] --> P3G["Collector
Gateway"] P3G --> P3B1["Backend 1"] P3G --> P3B2["Backend 2"] end style P1C fill:#e94560,stroke:#fff,color:#fff style P2C fill:#e94560,stroke:#fff,color:#fff style P3G fill:#e94560,stroke:#fff,color:#fff

Ba deployment patterns phổ biến cho OTel Collector

Pattern Ưu điểm Nhược điểm Phù hợp khi
Sidecar Isolation tốt, config riêng per service Resource overhead cao Multi-tenant, compliance strict
DaemonSet Resource hiệu quả, dễ quản lý Shared config, noisy neighbor Phần lớn workloads K8s
Gateway Central control, multi-backend routing Single point of failure Tổ chức lớn, nhiều backends

Checklist triển khai production

  1. Bắt đầu với auto-instrumentation — SDK hoặc zero-code. Không cần custom spans ngay từ đầu
  2. Triển khai Collector trước backend — luôn đi qua Collector, không export trực tiếp từ SDK đến backend
  3. Cấu hình tail sampling sớm — giữ 100% error traces, sample traces bình thường để kiểm soát chi phí
  4. Filter health check spans — /health, /ready, /metrics tạo ra noise khổng lồ
  5. Thêm resource attributes — service.name, service.version, deployment.environment bắt buộc
  6. Monitor the monitor — Collector cũng phải được observability (self-telemetry, /healthz endpoint)
  7. Cân nhắc OBI — chạy song song cho third-party services và baseline visibility

9. So sánh OTel với các giải pháp khác

Tiêu chí OpenTelemetry Datadog Agent Elastic APM AWS X-Ray
Vendor lock-in❌ Không✅ CaoTrung bình✅ AWS only
Chi phí licenseMiễn phí (OSS)Trả phíBasic miễn phíTrả phí theo usage
Ngôn ngữ hỗ trợ12+ ngôn ngữ10+ ngôn ngữ7 ngôn ngữ5 ngôn ngữ
eBPF instrumentation✅ OBI✅ USM
Declarative config✅ StableYAML riêngYAML riêngJSON riêng
CommunityCNCF, 1000+ contributorsProprietaryElastic communityAWS only
Backend flexibilityBất kỳ OTLP backendChỉ DatadogChủ yếu ElasticChỉ AWS

10. Kết luận

OpenTelemetry đã chuyển từ "dự án triển vọng" thành tiêu chuẩn không thể bỏ qua cho mọi hệ thống phân tán. Với declarative configuration stable, OBI eBPF instrumentation beta, và ecosystem SDK trưởng thành trên mọi ngôn ngữ chính — chi phí adopt OTel chưa bao giờ thấp đến vậy, trong khi giá trị mang lại ngày càng rõ ràng.

Nếu bạn đang xây dựng hệ thống trên .NET, Node.js, Go, hay bất kỳ stack nào — hãy bắt đầu với auto-instrumentation + Collector. Khi đã có baseline visibility, thêm custom spans cho business events và cân nhắc OBI cho infrastructure layer. Observability không phải luxury — nó là nền tảng để vận hành hệ thống phân tán hiệu quả.

Tóm tắt hành động

  • Bước 1: Cài đặt OTel SDK / auto-instrumentation cho stack hiện tại
  • Bước 2: Triển khai OTel Collector (DaemonSet hoặc sidecar)
  • Bước 3: Cấu hình tail sampling + filter health checks
  • Bước 4: Kết nối với backend (Grafana LGTM stack miễn phí cho self-host)
  • Bước 5: Thử nghiệm OBI trên một cluster Linux cho zero-code visibility

Nguồn tham khảo