rafal-slowik / traceparent-plugin

MIT License
0 stars 0 forks source link
traefik traefik-plugin traefik-plugin-catalog traefik-plugins-catalog

traceparent-plugin

The puropse of this middleware plugin is to set the OTEL traceparent header to the request in case it's not provided yet, and it's constructed based on a given header, which will serve as trace_id. Then the value used by the trace_id will be forwarded to subsequent services and potentially can be used as a transaction ID in monitoring tools.

The header can look as follows:

traceparent: 00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01

The traceparent header's structure consists of:

{version}-{trace_id}-{span_id}-{trace_flags}  

The middleware expects the parameter HeaderName, which is the name of the header, which is will be consiered the trace_id and will be evaluated if it's a valid 32-character hexadecimal string, e.g.  

80e1afed08e019fc1110464cfa66635c

The configuration below, shows how to configure the middleware with the name test-middleware to chek and evaluate the header X-Appgw-Trace-Id and treat it header as trace-id:

- "traefik.http.middlewares.test-middleware.plugin.traceparent-plugin.HeaderName=X-Appgw-Trace-Id"

If for example the header X-Appgw-Trace-Id has a value 91e1afed08e019fc2210464cfa66638c, and traceparent header is not set yet, then the header will be constructed and attached to the request.

TThe span ID will be generated by the plugin and added to the header, for instance 8a085854422dd6d5

traceparent: 00-91e1afed08e019fc2210464cfa66638c-8a085854422dd6d5-01

The traceparent is constructed in the following way by the plugin:

version = 00

trace_flags = 01

trace_id = taken from the header specified and must be valid

span_id = generated 16 hexadecimal string

{version}-{trace_id}-{span_id}-{trace_flags}

The edge cases:

An example docker-compose setup:

version: "3.8"

services:
  traefik:
    image: traefik:v3.2
    container_name: traefik
    command:
      - --api.insecure=true
      - "--log.level=DEBUG"
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --experimental.plugins.traceparent-plugin.moduleName=github.com/rafal-slowik/traceparent-plugin
      - --experimental.plugins.traceparent-plugin.version=v0.0.3
    ports:
      - "80:80"
      - "8080:8080" # Traefik dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  test-service:
    image: traefik/whoami
    container_name: whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.test-service.rule=Host(`localhost`)"
      - "traefik.http.routers.test-service.entrypoints=web"
      - "traefik.http.middlewares.test-middleware.plugin.traceparent-plugin.HeaderName=X-Appgw-Trace-Id"
      - "traefik.http.routers.test-service.middlewares=test-middleware"
      - "traefik.http.services.test-service.loadbalancer.server.port=80"