Signal Forge ADR-009: K8s attribute enrichment at collector (not in SDK)
Status: Accepted
Decision: K8s pod/namespace/deployment attributes are added by otelcol.processor.k8sattributes
in the
Helm-managed Alloy stack,
not by the application SDK.
Rationale:
- Application code should not know about Kubernetes. K8s attributes are infrastructure metadata.
- Centralised enrichment means adding a new service to the cluster gets K8s attributes automatically — no SDK change required.
- The k8sattributes processor uses the OTLP connection source IP to look up the pod in the Kubernetes API, which is accurate and requires no application-side configuration.
- The processor requires a ClusterRole with
get/list/watchonpodsandnodes. This is one configuration point for the entire cluster, not per-service.
Alternative considered: OTEL_RESOURCE_ATTRIBUTES env var per Deployment — rejected because it
requires manual maintenance and is inaccurate (pod name changes on each restart; it would always
show the previous name unless the env var uses the Downward API).
Local graph
Linked from 2 notes
Signal Forge ADR-004: Helm-managed Alloy stack (grafana/k8s-monitoring)
Standardizes on the grafana/k8s-monitoring Helm chart's five-role Alloy topology, keeping the hand-rolled DaemonSet only as a non-deployed reference.
Signal Forge ADR-005: Separate collector configmaps per deployment mode
Keeps cloud and local Alloy collector configs in separate files rather than one conditional configmap, so each mode's exporters stay explicit and uncoupled.
Related notes
Signal Forge ADR-005: Separate collector configmaps per deployment mode
Keeps cloud and local Alloy collector configs in separate files rather than one conditional configmap, so each mode's exporters stay explicit and uncoupled.
Signal Forge ADR-003: Span metrics generated before tail sampling
Places the spanmetrics connector ahead of tail_sampling so RED metrics reflect all traffic instead of only the ~25% of traces that survive sampling.
Signal Forge ADR-002: SpanLink for async RabbitMQ propagation (not parent-child)
Uses a SpanLink, not a parent-child span relationship, to connect RabbitMQ consumer spans back to the producer span across async, retry-prone delivery.
Architecture Overview
Signal Forge's topology, service communication, trace propagation, and per-signal pipeline flow across local and Grafana Cloud deployment modes.