From f721df30632d4ea507d7711380b151077dc26a96 Mon Sep 17 00:00:00 2001 From: Movses Aslanyan Date: Mon, 12 Oct 2026 20:09:38 +0330 Subject: [PATCH] Auto-instrument sanctions with OpenTelemetry zero-code Add opentelemetry-distro/exporter-otlp (pinned pair) and run opentelemetry-bootstrap at build time; wrap the sanctions command with opentelemetry-instrument and configure the SDK via OTEL_* env (traces only, OTLP/HTTP to otlp.vione.cloud). create-secrets.sh now writes the base64 OTLP auth header into .env.observability. The G10 guard test (no observability libraries in requirements) is expected to fail from here until the guard suite is retired in Phase 3. Co-Authored-By: Claude Opus 5.5 --- Dockerfile | 1 + docker-compose.yml | 11 ++++++++++- k8s/create-secrets.sh | 10 ++++++++-- requirements.txt | 2 ++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index c6d3959..3cf65ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt +RUN opentelemetry-bootstrap -a install COPY common ./common COPY services ./services diff --git a/docker-compose.yml b/docker-compose.yml index 2ba5ab1..4f6cbf9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -139,7 +139,16 @@ services: environment: <<: *app-env SERVICE_NAME: sanctions - command: uvicorn services.sanctions.app:app --host 0.0.0.0 --port 8003 --reload --no-access-log + OTEL_SERVICE_NAME: sanctions + OTEL_RESOURCE_ATTRIBUTES: deployment.environment.name=prod + OTEL_EXPORTER_OTLP_ENDPOINT: https://otlp.vione.cloud + OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf + OTEL_TRACES_EXPORTER: otlp + OTEL_METRICS_EXPORTER: none + OTEL_LOGS_EXPORTER: none + env_file: + - .env.observability + command: opentelemetry-instrument uvicorn services.sanctions.app:app --host 0.0.0.0 --port 8003 --reload --no-access-log ports: - "8003:8003" healthcheck: diff --git a/k8s/create-secrets.sh b/k8s/create-secrets.sh index 7392f24..80dc393 100755 --- a/k8s/create-secrets.sh +++ b/k8s/create-secrets.sh @@ -10,7 +10,8 @@ # (Prometheus, Alertmanager, Loki, Tempo, Alloy UI, OTLP) # grafana-admin Grafana admin user/password # and writes .env.observability at the repo root (gitignored) for the czy-side -# Alloy log agent; copy it to the server once (see k8s/README.md). +# Alloy log agent and the OTLP auth header of instrumented services; copy it to +# the server after every regeneration (see k8s/README.md). # # KUBECTL defaults to `kubectl`; e.g. KUBECTL="ssh falken kubectl" to run it on # the node when the API server isn't reachable from here. @@ -47,14 +48,19 @@ kubectl create secret generic grafana-admin -n "$NS" \ --from-literal=admin-password="$GRAFANA_ADMIN_PASSWORD" \ --dry-run=client -o yaml | $KUBECTL apply -f - +# OTLP header for instrumented services: URL-encoded (space -> %20), and +# newlines stripped because GNU base64 wraps at 76 chars and this is ~80. +OTLP_BASIC=$(printf '%s:%s' "$OBS_USER" "$OBS_PASSWORD" | base64 | tr -d '\n') + ( umask 077 cat > ../.env.observability <