image for post

HAProxy + W3C traceparent

Участники Opentelemetry сделали W3C стандарт про traceparent пока он в статусе черновика (draft), но больших изменений думаю уже не будет.

У HAProxy есть настройки связанные с request-id, можно указывать формат unique-id-format / unique-id-header, однако формата подходящего из коробки нет и придется читать стандарт.

Для тех кому лень смотреть traceparent выглядит так: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01 и имеет формат
${version}-${trace-id}-${parent-id}-${trace-flags}.

Версия на данный момент только одна - 00. trace-flag - это флаги и пока их только 2 первый (least significant bit, right-most) отвечает за семплинг, второй бит говорит о случайности байт в trace-id.
Решение по семплингу будет принимать не HAProxy, так что просто захардкодим флаги в 03.

Парсить входящий traceparent я не буду (добавить несложно, но я специально делаю свой traceparent, не учитывая входящий), поэтому задача сводится к сгенерировать header формата: 00-${rand_32_hex}c-${rand_16_hex}-03 на HAProxy.

В HAProxy для генерации случайных строк можно использовать uuid(4) RFC 4122.

Поехали..

Делаем стенд и настраиваем HAProxy

Создадим конфиг для helm чарта haproxy-ingress, обзовем файлик haproxy-traceparent.yaml:

serviceAccount:
  create: false
controller:
  ingressClass: haproxy
  ingressClassResource:
    enabled: true
    default: false
    controllerClass: "haproxy"
  # [Configuration keys](https://haproxy-ingress.github.io/docs/configuration/keys/#keys)
  config:
    config-frontend: |-
      # parse UUID [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122.html)
      http-request set-var(txn.trace_id) uuid(4),regsub(\"^([^-]{8})-([^-]{4})-([^-]{4})-([^-]{4})-([^-]{12})$\",\"\1\2\3\4\5\")
      http-request set-var(txn.parent_id) uuid(4),regsub(\"^([^-]{8})-([^-]{4})-([^-]{4})-([^-]{4})-([^-]{12})$\",\"\1\2\3\")
      unique-id-format 00-%[var(txn.trace_id)]-%[var(txn.parent_id)]-03
      unique-id-header traceparent
      # return traceparent to the client
      http-after-response set-header traceparent %ID

Устанавливаем HAProxy:

helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts
helm upgrade -i haproxy haproxy-ingress/haproxy-ingress -f haproxy-traceparent.yaml

Для проверки поставим podinfo, podinfo-local.yaml:

ingress:
  enabled: true
  className: "haproxy"
  hosts:
    - host:
      paths:
        - path: /
          pathType: ImplementationSpecific

Устанавливаем:

helm repo add podinfo https://stefanprodan.github.io/podinfo
helm upgrade -i podinfo podinfo/podinfo -f podinfo-local.yaml

Пошли тестить:

curl -i http://localhost:80/headers

> HTTP/1.1 200 OK
> content-type: application/json; charset=utf-8
> x-content-type-options: nosniff
> content-length: 358
> traceparent: 00-5e8097d048e64fd4a4fc1861d9032e17-6ee9491181244f5b-03

> {
>   ...
>   "Traceparent": [
>     "00-5e8097d048e64fd4a4fc1861d9032e17-6ee9491181244f5b-03"
>   ],
> }

Готово.

Copyright © 2023

Version: 0.2.24

Настройки: