Собираем всё, что изучили: два сервиса → OTel Collector (с фильтрацией и батчингом) → Jaeger с Elasticsearch. Этот стенд — основа всех практикумов дальше.
docker-compose.yml
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports: ["9200:9200"]
jaeger:
image: jaegertracing/all-in-one:latest
environment:
- SPAN_STORAGE_TYPE=elasticsearch
- ES_SERVER_URLS=http://elasticsearch:9200
ports:
- "16686:16686" # UI
- "14268:14268" # legacy-приём
depends_on: [elasticsearch]
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel/config.yaml"]
volumes:
- ./otel-config.yaml:/etc/otel/config.yaml
ports:
- "4317:4317" # OTLP gRPC — сюда шлют приложения
- "4318:4318" # OTLP HTTP
depends_on: [jaeger]
otel-config.yaml
receivers:
otlp:
protocols:
grpc: {}
http: {}
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
attributes/strip:
actions:
- key: db.statement
action: delete # PII-политика: не хранить SQL-тексты
filter/noise:
traces:
span:
- 'attributes["http.route"] == "/health"'
batch:
send_batch_size: 512
timeout: 3s
exporters:
otlp/jaeger:
endpoint: jaeger:4317
tls: { insecure: true }
debug:
verbosity: basic
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, attributes/strip, filter/noise, batch]
exporters: [otlp/jaeger]
Приложения
Те же service-a/service-b из практикума 1.4, но теперь:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 # в Collector, не в Jaeger!
Чек-лист проверки стенда
docker compose up -d; ES поднялся (не экономьте: ему нужен 1+ ГБ heap);- дёргайте
curl localhost:8080/doиcurl localhost:8081/health; - UI: трейсы service-a есть, спанов /health нет — работает filter;
- откройте SQL-спан:
db.statementотсутствует — работает attributes/strip; - рестарт ES:
docker compose restart elasticsearch— после подъёма трейсы снова пишутся (Collector пережил паузу очередью).
Задания
- Добавьте третий сервис service-c, вызываемый из B: убедитесь, что трейс стал трёхзвенным без изменения конфигов Collector.
- Вынесите processor
resource: добавьте всем спанамdeployment.environment=dev; проверьте в UI процесс-теги. - Замерьте задержку появления трейса в UI (создали запрос → увидели в поиске) и объясните её слагаемые: batch timeout + запись ES + окно поиска UI.
- Нагрузочный тест: 100 RPS на /do в течение 5 минут; следите за памятью Collector и отставанием ES (почта ошибок экспорта в логах).
Мини-квиз
1. Почему приложения шлют в Collector, а не прямо в Jaeger? — Развязка: фильтры, PII, батчинг, смена бэкенда без правки приложений.
2. Что проверяют спаны /health? — Что filter-процессор действительно отсеивает шум до экспорта.
3. Почему трейсы появились после рестарта ES? — Collector буферизовал и с ретраями доставил после восстановления.