Wire OpenTelemetry tracing — HTTP, B2, APNs, FCM, asynq, GORM (partial)
Step 1 — OTel SDK: cmd/api and cmd/worker initialize a tracer provider that exports OTLP/HTTP to obs.88oakapps.com (Jaeger all-in-one). Sampling is AlwaysSample in dev (DEBUG=true) and TraceIDRatioBased(0.1) in prod, overridable via OTEL_TRACES_SAMPLER_ARG. Service names are honeydue-api and honeydue-worker. otelecho.Middleware opens a span per HTTP request. Step 2 — Manual spans: storage_service.Upload now takes ctx and emits storage.upload + b2.PutObject spans (size_bytes, key, mime_type, bucket, result attrs). APNs Send/SendWithCategory and FCM sendOne emit per-token spans with topic, status_code, reason. Asynq middleware emits asynq.handle:<task_type> per job with retry/payload attrs and records asynq_job_duration_seconds. Step 3 — Database: otelgorm plugin registered in database.Connect, so any SQL emitted via db.WithContext(ctx) attaches to the request span. Every repository now exposes WithContext(ctx) *XRepository as the migration helper. TaskService.ListTasks and GetTasksByResidence are migrated end-to-end (ctx threaded through handler → service → repo); remaining services adopt the same pattern incrementally — pre-migration methods still emit untraced SQL via the unchanged db field. OBS_TRACES_URL and OBS_INGEST_TOKEN flow from deploy/prod.env → honeydue-secrets → api+worker Deployments via secretKeyRef (optional). 02-setup-secrets.sh sources them from prod.env on next run; manifests mark both env vars optional so the deployment rolls without traces if the secret is absent. ch15 observability doc now lists what produces spans today vs the remaining migration work, with the explicit per-method pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,22 @@ spec:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: B2_APP_KEY
|
||||
# Observability — push traces (and any future OTLP metrics) to
|
||||
# obs.88oakapps.com. Token gates ingest at nginx; URL is the
|
||||
# same one vmagent uses for metric remote-write. Both come from
|
||||
# honeydue-secrets so they aren't world-readable in ConfigMap.
|
||||
- name: OBS_TRACES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: OBS_TRACES_URL
|
||||
optional: true
|
||||
- name: OBS_INGEST_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: OBS_INGEST_TOKEN
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- name: apns-key
|
||||
mountPath: /secrets/apns
|
||||
|
||||
@@ -74,6 +74,21 @@ spec:
|
||||
name: honeydue-secrets
|
||||
key: REDIS_PASSWORD
|
||||
optional: true
|
||||
# Observability — workers emit traces (e.g., asynq job spans) to
|
||||
# obs.88oakapps.com over OTLP/HTTP. service.name=honeydue-worker
|
||||
# so api and worker show up as separate services in Jaeger.
|
||||
- name: OBS_TRACES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: OBS_TRACES_URL
|
||||
optional: true
|
||||
- name: OBS_INGEST_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: honeydue-secrets
|
||||
key: OBS_INGEST_TOKEN
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- name: apns-key
|
||||
mountPath: /secrets/apns
|
||||
|
||||
@@ -70,6 +70,24 @@ if [[ -n "${REDIS_PASSWORD}" ]]; then
|
||||
SECRET_ARGS+=(--from-literal="REDIS_PASSWORD=${REDIS_PASSWORD}")
|
||||
fi
|
||||
|
||||
# Observability ingest credentials live in deploy/prod.env (gitignored) so
|
||||
# the values aren't checked into config.yaml. Skipped silently when the
|
||||
# file or keys are absent — the api/worker manifests mark these env vars
|
||||
# optional, so the deployment still rolls without traces.
|
||||
PROD_ENV_FILE="${DEPLOY_DIR}/../deploy/prod.env"
|
||||
if [[ -f "${PROD_ENV_FILE}" ]]; then
|
||||
OBS_TOKEN_VAL="$(grep -E '^OBS_INGEST_TOKEN=' "${PROD_ENV_FILE}" 2>/dev/null | cut -d= -f2- || true)"
|
||||
OBS_URL_VAL="$(grep -E '^OBS_TRACES_URL=' "${PROD_ENV_FILE}" 2>/dev/null | cut -d= -f2- || true)"
|
||||
if [[ -n "${OBS_TOKEN_VAL}" ]]; then
|
||||
log " Including OBS_INGEST_TOKEN in secrets"
|
||||
SECRET_ARGS+=(--from-literal="OBS_INGEST_TOKEN=${OBS_TOKEN_VAL}")
|
||||
fi
|
||||
if [[ -n "${OBS_URL_VAL}" ]]; then
|
||||
log " Including OBS_TRACES_URL in secrets"
|
||||
SECRET_ARGS+=(--from-literal="OBS_TRACES_URL=${OBS_URL_VAL}")
|
||||
fi
|
||||
fi
|
||||
|
||||
kubectl create secret generic honeydue-secrets \
|
||||
"${SECRET_ARGS[@]}" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
Reference in New Issue
Block a user