image for post

HAProxy + W3C traceparent

Opentelemetry contributers created a W3C draft about traceparent.

HAProxy has settings related to request-id, you can specify unique-id-format / unique-id-header, although you can't use w3c traceparent out of the box, so let's read the standard.

TLDR: traceparent looks like: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01 and has the format:
${version}-${trace-id}-${parent-id}-${trace-flags}.

traceparent version is always 00 (there is no other versions yet). trace-flag - are 2 flags. Least significant bit, right-most is a sampling indicator and another is indicator of randomness in trace-id. HAProxy won't do anything about sampling in my case, thus we can hardcode the flag value 03.

I won't parce incomming traceparent (you can add it if you need), thus we should generate header in forma: 00-${rand_32_hex}c-${rand_16_hex}-03 на HAProxy.

In HAProxy configuration as generator of random strings we can use uuid(4) RFC 4122.

Let's go..

Install & Practice

Let's create a helm chart config haproxy-ingress, file 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

Let's install HAProxy:

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

Install podinfo for testing, podinfo-local.yaml:

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

Install:

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

Done, let's test:

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"
>   ],
> }

Done.

Copyright © 2023

Version: 0.2.24

Settings: