Jaeger
Hiểu kiến trúc Jaeger và gửi, truy vấn, xử lý sự cố traces qua pipeline OpenTelemetry dùng OTLP.
Jaeger là một backend distributed tracing: nó nhận spans, lưu chúng và cung cấp API cùng giao diện để tìm trace. Với hệ thống OpenTelemetry mới, đường ingest nên là OTLP thay vì exporter hoặc protocol Jaeger cũ.
Đường đi được khuyến nghị
Giữ ứng dụng độc lập với backend bằng pipeline OpenTelemetry SDK → OTLP → OpenTelemetry Collector → OTLP → Jaeger. Jaeger hỗ trợ OTLP native trên cổng
4317 và 4318; không cần cài Jaeger exporter cũ trong SDK hoặc Collector.
Mục lục
- Jaeger nằm ở đâu trong pipeline
- Kiến trúc từ SDK đến Jaeger
- Lab có thể chạy bằng Docker Compose
- Cấu hình SDK và gửi trace mẫu
- Truy vấn và xác minh trong Jaeger UI
- Đọc attributes trong Jaeger
- Troubleshooting
- Ghi chú production
- Nguồn chính thức và bài liên quan
Jaeger nằm ở đâu trong pipeline
Jaeger trả lời các câu hỏi như “request nào chậm?”, “span nào lỗi?” và “dịch vụ nào nằm trên critical path?”. Nó không thay thế OpenTelemetry SDK hoặc Collector. Jaeger hiện chỉ lưu traces; gửi metrics hay logs vào cùng endpoint OTLP không biến Jaeger thành backend cho hai signal đó.
Các thành phần cần phân biệt
| Thành phần | Trách nhiệm | Ví dụ trong bài |
|---|---|---|
| Instrumentation | Tạo span quanh HTTP, database hoặc công việc nghiệp vụ | HTTP server tạo span POST /checkout |
| OpenTelemetry SDK | Gắn Resource, sampling, batching và export | service.name=checkout-api, OTLP/HTTP exporter |
| OpenTelemetry Collector | Nhận, xử lý, buffer và chuyển tiếp telemetry | otlp receiver, batch processor, otlp_grpc exporter |
| Jaeger collector role | Nhận spans và ghi vào trace storage | OTLP receiver của Jaeger trên 4317/4318 |
| Trace storage | Lưu spans và index dữ liệu cần tìm kiếm | Memory trong lab; external storage trong production |
| Jaeger query role và UI | Đọc storage, phục vụ API và giao diện | UI trên 16686 |
Span là một đơn vị công việc có thời điểm bắt đầu, kết thúc và metadata.
Nhiều spans có cùng trace_id tạo thành trace. Quan hệ parent_span_id ghép
chúng thành cây nhân quả thay vì chỉ là danh sách cùng ID.
Jaeger v2 là một distribution chuyên biệt xây trên framework OpenTelemetry
Collector. Nó có thể chạy nhiều role — vai trò triển khai — như collector,
query, ingester hoặc all-in-one. External OpenTelemetry Collector vẫn hữu
ích khi bạn cần một gateway chung cho traces, metrics, logs, enrichment, routing
hoặc tail sampling.
OTLP là đường ingest khuyến nghị
Jaeger nhận OTLP ổn định ở hai transport:
| Đường ingest | Endpoint mặc định | Khi dùng |
|---|---|---|
| OTLP/gRPC | jaeger:4317 | Kết nối service-to-service hỗ trợ HTTP/2; Collector exporter trong lab |
| OTLP/HTTP | http://jaeger:4318/v1/traces | Môi trường ưu tiên HTTP hoặc cần gửi OTLP JSON/Protobuf |
Các API Jaeger Thrift, UDP và Jaeger Protobuf cũ được duy trì cho tương thích và đã được đánh dấu deprecated trong tài liệu Jaeger. Chúng không phải lựa chọn cho pipeline mới. Tương tự, tên backend “Jaeger” không yêu cầu ứng dụng dùng Jaeger propagation header; W3C Trace Context vẫn là propagation mặc định phù hợp.
Đừng nhầm ingest với propagation
OTLP chuyển spans đã ghi từ SDK đến Collector hoặc backend. Propagation chuyển
traceparent qua request nghiệp vụ giữa hai service để service sau tạo đúng
child span. Đổi exporter sang Jaeger không tự sửa một trace bị đứt do thiếu
propagation.
Kiến trúc từ SDK đến Jaeger
Mỗi mũi tên là một failure boundary riêng. HTTP success từ SDK tới Collector chỉ chứng minh Collector đã nhận request đó. Collector vẫn có thể filter, hết queue, không kết nối được Jaeger hoặc bị backend từ chối. Vì vậy, xác minh phải đi từ ứng dụng đến receiver, exporter, storage rồi cuối cùng mới đến query UI.
Đặt Collector ở giữa đem lại ba lợi ích thực tế:
- ứng dụng chỉ biết OTLP endpoint, không giữ cấu hình riêng của Jaeger;
- processors có thể batch, redact, thêm Resource hoặc áp dụng sampling có chủ đích;
- cùng Collector có thể route metrics và logs tới backend khác mà không ép Jaeger nhận signal nó không lưu.
Collector không bắt buộc nếu SDK chỉ gửi traces và Jaeger là đích duy nhất. Tuy nhiên, gửi thẳng vẫn nên dùng OTLP. Hãy thêm Collector khi cần một policy boundary hoặc vận hành nhiều signal, không chỉ để tăng số hop.
Lab có thể chạy bằng Docker Compose
Lab này chạy Jaeger v2 all-in-one với memory storage và một Collector độc lập. Các version được pin để cấu hình có thể tái lập; hãy đọc release notes trước khi nâng version.
Chỉ dùng cho local
Memory storage mất dữ liệu khi Jaeger restart. Pipeline dùng plaintext, không có authentication và bind các cổng lên máy local. Không đưa topology này ra Internet hoặc gọi nó là cấu hình production.
Tạo file Compose
Tạo thư mục trống, rồi lưu nội dung sau thành docker-compose.yaml:
services:
jaeger:
image: cr.jaegertracing.io/jaegertracing/jaeger:2.20.0
environment:
JAEGER_LISTEN_HOST: 0.0.0.0
ports:
- "16686:16686" # UI và HTTP query API
- "13133:13133" # healthcheckv2 /status
collector:
image: otel/opentelemetry-collector-contrib:0.157.0
command:
- "--config=/etc/otelcol-contrib/config.yaml"
volumes:
- ./collector-config.yaml:/etc/otelcol-contrib/config.yaml:ro
depends_on:
- jaeger
ports:
- "4317:4317" # SDK -> Collector bằng OTLP/gRPC
- "4318:4318" # SDK -> Collector bằng OTLP/HTTPJaeger không cần publish cổng OTLP ra host trong topology này. Collector gọi
jaeger:4317 qua network nội bộ của Compose. Việc chỉ publish endpoint của
Collector cũng làm ranh giới ingest dễ quan sát hơn.
Tạo cấu hình Collector
Lưu file sau cạnh Compose dưới tên collector-config.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_mib: 256
batch:
send_batch_size: 512
timeout: 1s
exporters:
debug:
verbosity: basic
otlp_grpc/jaeger:
endpoint: jaeger:4317
tls:
insecure: true
sending_queue:
enabled: true
queue_size: 2048
retry_on_failure:
enabled: true
initial_interval: 1s
max_interval: 10s
max_elapsed_time: 1m
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [debug, otlp_grpc/jaeger]otlp_grpc/jaeger là một instance của OTLP/gRPC exporter. Phần sau dấu / chỉ
là tên định danh để logs và metrics dễ đọc; nó không chọn một Jaeger protocol
riêng. tls.insecure: true cho phép kết nối plaintext trong network local.
debug tạo một nhánh fan-out để chứng minh spans đã tới cuối pipeline. Gỡ nhánh
này sau lab vì log telemetry chi tiết có thể tốn I/O và làm lộ dữ liệu.
Khởi động và kiểm tra health
1. Kiểm tra Compose đã render đúng
docker compose configLệnh này phát hiện lỗi YAML và đường mount hiển nhiên. Validation cuối cùng vẫn do đúng binary Collector thực hiện khi container khởi động.
2. Khởi động hai service
docker compose up -d
docker compose psdepends_on chỉ quyết định thứ tự tạo container. Collector có thể log retry ngắn
trong lúc Jaeger chưa sẵn sàng.
3. Kiểm tra Jaeger và Collector
curl --fail http://localhost:13133/status
docker compose logs --tail=100 collector
docker compose logs --tail=100 jaegerHealth success cho biết process Jaeger đang phục vụ endpoint quản trị. Nó chưa chứng minh một trace đã đi hết pipeline; bước xác minh dữ liệu nằm ở phần sau.
Nếu Collector báo unknown type: otlp_grpc, hãy kiểm tra image/distribution và
version thực tế. Không đổi ngược sang Jaeger exporter cũ để né lỗi component.
Cấu hình SDK và gửi trace mẫu
Cấu hình ứng dụng thật
SDK cụ thể có thể khác về package và mức hỗ trợ environment variables. Với SDK hỗ trợ cấu hình chuẩn, ứng dụng chạy trên host có thể gửi OTLP/HTTP như sau:
export OTEL_SERVICE_NAME=checkout-api
export OTEL_RESOURCE_ATTRIBUTES='service.version=1.4.0,deployment.environment.name=local'
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_TRACES_SAMPLER=parentbased_always_onNếu ứng dụng chạy trong cùng Compose network, endpoint là
http://collector:4318. Với OTLP/gRPC, dùng endpoint http://localhost:4317 và
OTEL_EXPORTER_OTLP_PROTOCOL=grpc nếu SDK hỗ trợ.
parentbased_always_on phù hợp với lab vì giữ trace được bắt đầu local và tôn
trọng quyết định sampling của remote parent. Production cần policy theo lưu lượng,
chi phí và rủi ro dữ liệu; đừng sao chép sampler lab vào hệ thống tải lớn.
Gửi OTLP JSON bằng curl
Ví dụ sau giả lập hai spans: server span POST /checkout và child client span
POST payment. Nó dùng openssl để tạo IDs mới và in TRACE_ID để bạn truy vấn.
OTLP JSON yêu cầu các trường integer 64-bit như timestamp được biểu diễn bằng
chuỗi.
trace_id="$(openssl rand -hex 16)"
root_span_id="$(openssl rand -hex 8)"
child_span_id="$(openssl rand -hex 8)"
now_ns=$(( $(date +%s) * 1000000000 ))
root_start=$(( now_ns - 1000000000 ))
child_start=$(( root_start + 200000000 ))
child_end=$(( child_start + 250000000 ))
root_end=$(( root_start + 800000000 ))
curl --fail-with-body --silent --show-error \
-X POST \
-H 'Content-Type: application/json' \
--data-binary @- \
http://localhost:4318/v1/traces <<JSON
{
"resourceSpans": [{
"resource": {
"attributes": [
{"key": "service.name", "value": {"stringValue": "checkout-api"}},
{"key": "service.version", "value": {"stringValue": "1.4.0"}},
{"key": "deployment.environment.name", "value": {"stringValue": "local"}}
]
},
"scopeSpans": [{
"scope": {"name": "jaeger-page-demo", "version": "1.0.0"},
"spans": [
{
"traceId": "${trace_id}",
"spanId": "${root_span_id}",
"name": "POST /checkout",
"kind": "SPAN_KIND_SERVER",
"startTimeUnixNano": "${root_start}",
"endTimeUnixNano": "${root_end}",
"attributes": [
{"key": "http.request.method", "value": {"stringValue": "POST"}},
{"key": "http.route", "value": {"stringValue": "/checkout"}},
{"key": "http.response.status_code", "value": {"intValue": "200"}},
{"key": "checkout.cart.items", "value": {"intValue": "3"}}
],
"events": [{
"timeUnixNano": "${child_end}",
"name": "payment.authorized",
"attributes": [
{"key": "payment.provider", "value": {"stringValue": "sandbox"}}
]
}],
"status": {"code": "STATUS_CODE_OK"}
},
{
"traceId": "${trace_id}",
"spanId": "${child_span_id}",
"parentSpanId": "${root_span_id}",
"name": "POST payment",
"kind": "SPAN_KIND_CLIENT",
"startTimeUnixNano": "${child_start}",
"endTimeUnixNano": "${child_end}",
"attributes": [
{"key": "server.address", "value": {"stringValue": "payments.local"}},
{"key": "server.port", "value": {"intValue": "443"}}
],
"status": {"code": "STATUS_CODE_OK"}
}
]
}]
}]
}
JSON
export TRACE_ID="${trace_id}"
printf 'TRACE_ID=%s\n' "${TRACE_ID}"Một response OTLP thành công xác nhận Collector đã nhận request. Processor batch
có thể chờ tối đa một giây trong cấu hình này trước khi export. Xem log Collector
để xác nhận nhánh debug, rồi chuyển sang UI để chứng minh backend đã lưu trace.
Truy vấn và xác minh trong Jaeger UI
Tìm theo service và operation
Mở Jaeger UI. Trên trang tìm trace:
- chọn service
checkout-api; - chọn operation
POST /checkoutnếu danh sách operation đã cập nhật; - giữ time range bao phủ vài phút gần nhất;
- bấm Find Traces rồi mở kết quả mới nhất.
Trace hợp lệ phải có hai spans. POST payment phải nằm dưới
POST /checkout, cùng trace ID nhưng có span ID riêng. Timeline phải cho thấy
child span nằm trong khoảng thời gian của root span.
Trong trace detail, kiểm tra các bằng chứng cụ thể:
- service là
checkout-api, không phảiunknown_service; - Resource có
service.version=1.4.0vàdeployment.environment.name=local; - root span có route
/checkout, status code200và eventpayment.authorized; - child span có parent đúng và peer
payments.localnếu UI/backend suy ra được từ semantic attributes; - thời lượng root khoảng
800 ms, child khoảng250 ms.
Kiểm tra theo trace ID
UI cho phép mở trace từ ID đã in. Bạn cũng có thể dùng HTTP endpoint mà chính Jaeger UI hiện dùng để chẩn đoán local:
curl --fail --silent \
"http://localhost:16686/api/traces/${TRACE_ID:?hãy chạy script gửi trace trước}" \
| jq .HTTP API nội bộ không phải integration contract
Đường /api/traces/{trace-id} là internal JSON API và có thể thay đổi. Dùng
jaeger.api_v3.QueryService trên gRPC 16685 hoặc HTTP /api/v3/* theo tài
liệu Jaeger cho tích hợp có yêu cầu compatibility; chỉ dùng lệnh trên để debug
stack local.
Nếu query theo ID có dữ liệu nhưng search theo service không có, ingestion đã
thành công. Hãy tập trung vào service.name, time range và index/search của
storage thay vì exporter.
Đọc attributes trong Jaeger
Jaeger UI thường dùng từ tags cho metadata hiển thị và tìm kiếm. Trong OpenTelemetry, cần phân biệt Resource, span attributes, instrumentation scope, events và status vì chúng có lifecycle khác nhau dù UI có thể đặt gần nhau.
Resource attributes và service identity
Resource mô tả entity tạo telemetry. service.name là định danh quan trọng
nhất để Jaeger nhóm và liệt kê service. Nên đặt thêm:
service.namespacekhi nhiều team có service trùng tên;service.versionđể so sánh release;deployment.environment.nameđể phân biệt local, staging và production;service.instance.idkhi cần khoanh một replica cụ thể.
Giữ service.name ổn định và low-cardinality. Không thêm pod UID, tenant ID hoặc
version vào chính tên service. Các giá trị thay đổi theo instance nên nằm ở
attribute tương ứng.
Nếu không đặt service.name, SDK có thể tạo tên mặc định như
unknown_service. Jaeger vẫn có thể lưu span, nhưng tìm kiếm, dependency graph và
ownership trở nên khó dùng.
Span attributes, events và status
Span attributes mô tả một operation. Ví dụ http.route=/checkout phù hợp để
group, còn URL chứa order ID động dễ làm tăng cardinality của index. Ưu tiên
semantic conventions thay vì tự tạo
httpMethod, statusCode hoặc peerHost.
Event là một mốc có timestamp bên trong span, ví dụ payment.authorized hoặc
exception. Event phù hợp với chi tiết xảy ra tại một thời điểm; nó không thay
thế child span cho một operation có duration riêng.
Status biểu diễn kết quả của span. HTTP 500 không tự động bảo đảm status
OpenTelemetry là ERROR nếu instrumentation không áp dụng semantic convention
đúng. Khi UI không tô lỗi như mong đợi, kiểm tra cả status object, exception event
và http.response.status_code trong payload thực tế.
Tags có thể chứa dữ liệu nhạy cảm
Không ghi token, cookie, password, raw SQL chứa dữ liệu người dùng hoặc PII vào Resource, attributes hay events. Jaeger index và retention có thể nhân rộng phạm vi lộ dữ liệu. Redact tại SDK hoặc Collector trước khi export.
Troubleshooting
Khi trace không xuất hiện, đi theo từng hop thay vì đổi nhiều cấu hình cùng lúc:
Sai port, path hoặc protocol
| Triệu chứng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
HTTP 404 trên Collector hoặc Jaeger | Gửi OTLP/HTTP sai path | Dùng /v1/traces; base endpoint của SDK thường là http://host:4318 |
connection refused | Gọi nhầm host, port chưa publish hoặc process chưa listen | Kiểm tra từ đúng container/pod; localhost trong container là chính container đó |
gRPC UNAVAILABLE hoặc HTTP/2 lỗi | Gửi gRPC vào 4318, proxy không hỗ trợ gRPC hoặc backend chưa sẵn sàng | Ghép grpc với 4317; kiểm tra proxy HTTP/2 và logs hai đầu |
Parse error hoặc HTTP 400 | Payload không đúng OTLP JSON/Protobuf | So với OTLP schema; integer 64-bit trong JSON phải dùng chuỗi |
| Jaeger có process nhưng không có span | Jaeger chỉ được publish UI, Collector gọi sai DNS | Trong Compose dùng jaeger:4317, không dùng localhost:4317 từ Collector |
Không coi số cổng là sự thật tuyệt đối. Cổng có thể được override. Luôn đối chiếu receiver thực tế và transport exporter.
TLS và authentication
Lab dùng plaintext. Ở production, lỗi x509, hostname mismatch hoặc handshake
thường nằm ở ranh giới Collector → Jaeger:
ca_filephải tin CA ký certificate server;- hostname trong endpoint phải khớp SAN của certificate;
- mTLS cần cả client certificate và private key;
- authentication extension hoặc proxy phải được bật ở cả nơi khai báo lẫn
service.extensionsnếu thiết kế dùng nó; - không “sửa” lỗi bằng
insecure_skip_verifylâu dài.
Kiểm tra kết nối từ chính pod Collector. Một lệnh thành công trên laptop không chứng minh DNS, CA bundle hoặc network policy trong cluster đúng.
Sampling và missing spans
Sampling có thể xảy ra ở SDK hoặc Collector. Head sampling quyết định sớm khi span bắt đầu. Tail sampling chờ thấy nhiều spans của trace rồi mới quyết định giữ. Jaeger không thể khôi phục span chưa từng được record hoặc đã bị drop trước khi ingest.
Khi trace thiếu ngẫu nhiên:
- kiểm tra
trace_flagsvà sampler của root service; - xác nhận child service tôn trọng remote parent và dùng cùng propagation format;
- tìm filter, transform hoặc tail-sampling policy trong mọi Collector hop;
- kiểm tra
otelcol_exporter_enqueue_failed_*, send-failed metrics, queue capacity và log retry theo version Collector; - kiểm tra span limits, memory limiter, backend storage errors và retention;
- gọi
force_flush/shutdownkhi process ngắn hạn kết thúc.
Đừng đặt mọi sampler thành always_on trong production chỉ để chữa missing spans.
Đó có thể là biện pháp canary có thời hạn, nhưng cần quay lại policy volume và
privacy sau khi khoanh vùng lỗi.
Clock skew và thời gian truy vấn
Clock skew là chênh lệch đồng hồ giữa các host. Nó có thể làm child span trông như bắt đầu trước parent hoặc nằm ngoài timeline. Jaeger query có thuật toán điều chỉnh clock skew và hiển thị warning khi áp dụng; đây là điều chỉnh lúc đọc, không sửa timestamp gốc trong ứng dụng.
Cách xử lý đúng:
- đồng bộ NTP/chrony trên node và kiểm tra container dùng clock host;
- dùng timestamp do SDK/runtime tạo, không ghép timestamp từ nhiều nguồn;
- mở rộng time range khi clock lệch khiến trace nằm ngoài cửa sổ mặc định;
- đọc warning trong UI trước khi kết luận latency âm hoặc parent sai;
- với cấu hình Jaeger explicit, kiểm tra
jaeger_query.max_clock_skew_adjust.
Đặt max_clock_skew_adjust: 0s tắt adjustment nhưng không sửa đồng hồ. Chỉ thay
đổi sau khi hiểu vì sao thuật toán đang làm trace khó đọc.
Trace thiếu parent hoặc span chưa kết thúc
Nếu các service xuất hiện thành những trace riêng, lỗi thường ở propagation chứ
không phải Jaeger. Capture traceparent ở test path, xác nhận sender inject sau
khi client span active và receiver extract trước khi tạo server span. Không log
raw headers ở production.
Nếu span không xuất hiện cho tới khi process dừng hoặc luôn có duration sai:
- bảo đảm span được
endđúng một lần trên success, error và cancellation; - với process ngắn hạn, gọi SDK
force_flushrồishutdowncó timeout; - kiểm tra batch timeout ở cả SDK và Collector;
- không giữ active span vô hạn quanh thread pool hoặc background worker;
- dùng links thay cho parent khi công việc async thực sự không có quan hệ cây trực tiếp.
Ghi chú production
Topology, storage và scale
all-in-one với memory storage phù hợp cho local. Production nên chọn topology
và storage theo tải:
- tách
collectorrole ghi dữ liệu khỏiqueryrole đọc dữ liệu khi cần scale, policy mạng hoặc SLO khác nhau; - dùng external storage được release Jaeger đang chạy hỗ trợ, với retention, replication, backup và schema lifecycle rõ ràng;
- scale collectors và query services ngang vì chúng stateless khi state nằm ở external storage;
- cân nhắc Kafka làm persistent buffer giữa ingest và storage khi cần hấp thụ outage dài hoặc spike; khi đó phải vận hành thêm ingester và broker;
- chạy dependency aggregation hoặc SPM components cần thiết thay vì giả định UI tự suy ra mọi service graph từ trace storage;
- benchmark cả write, search và trace-by-ID với cardinality giống production.
All-in-one dùng Badger có thể phù hợp với lượng dữ liệu khiêm tốn theo tài liệu Jaeger, nhưng không scale ngang như external storage. Nói ngắn gọn: đừng chọn storage chỉ vì lab khởi động nhanh.
Reliability, security và vận hành
Checklist tối thiểu trước khi đưa Jaeger vào production:
- Pin version Jaeger, Collector và storage; đọc breaking changes cùng migration note.
- Bật TLS/mTLS hoặc authenticated gateway trên các trust boundary.
- Không expose ingest, query hoặc management port trực tiếp ra Internet.
- Tune sending queue, retry, timeout và persistent queue theo outage budget.
- Đặt memory limiter, CPU/memory requests, autoscaling signal và graceful shutdown.
- Định nghĩa sampling ownership; tránh hai tầng tail sampling không phối hợp.
- Monitor Collector accepted/refused/exported data cùng queue và retry metrics.
- Scrape Jaeger metrics, health, storage latency/error và query latency.
- Đặt retention, index strategy, cardinality budget và data-redaction policy.
- Test mất backend, restart Collector, rolling upgrade và storage restore.
- Tạo canary trace có
service.name, parent-child, error và attribute bắt buộc.
Queue và retry thường cho delivery at least once, vì timeout có thể xảy ra sau khi backend đã nhận nhưng trước khi Collector nhận ACK. Đừng giả định exactly-once. Cũng không dùng in-memory queue như persistent broker; restart có thể làm mất backlog.
Nguồn chính thức và bài liên quan
Nguồn chính được dùng cho mental model, cổng và cấu hình trong bài:
- Jaeger Architecture — roles, all-in-one, direct storage, Kafka và vị trí của OpenTelemetry Collector.
- Jaeger APIs — OTLP write APIs, cổng mặc định, query APIs và trạng thái legacy protocols.
- Jaeger Getting Started — image, UI và cấu hình all-in-one chính thức.
- Jaeger Configuration — YAML v2, storage/query extensions và clock-skew adjustment.
- OTLP exporter specification — endpoint, transport, TLS, timeout và retry.
- OpenTelemetry Collector OTLP exporter —
otlp_grpc, queue, retry và TLS client settings.
OTLP gRPC và OTLP HTTP
Phân biệt transport, endpoint, path và TLS.
Collector exporters
Cấu hình queue, retry, fan-out và kiểm chứng egress.
Sampling
Hiểu head sampling, tail sampling và missing spans.
Context propagation
Giữ parent-child relation qua service boundary.
Local observability stack
Thực hành stack local tối thiểu với Jaeger.