apiVersion: v1 kind: ConfigMap metadata: name: alloy-config namespace: observability labels: app.kubernetes.io/name: alloy app.kubernetes.io/component: log-collector data: config.river: | // ----------------------------------------------------------------------------- // Grafana Alloy — log collection only (metrics cluster+host collection is // handled by vmagent/node-exporter/cAdvisor elsewhere). // Forwards pod logs to the in-cluster Loki single-binary. // River config produced by `alloy convert -f promtail` from an equivalent // Promtail YAML (so component names and argument shapes are guaranteed // correct for Alloy v1.18). // ----------------------------------------------------------------------------- discovery.kubernetes "kubernetes_pods" { role = "pod" selectors { role = "pod" field = "spec.nodeName=" + coalesce(sys.env("HOSTNAME"), constants.hostname) } } loki.process "kubernetes_pods" { forward_to = [loki.write.default.receiver] // CRI-style log lines on the host: {"log":"...","stream":"stdout","time":"..."} stage.cri { } } discovery.relabel "kubernetes_pods" { targets = discovery.kubernetes.kubernetes_pods.targets rule { source_labels = ["__meta_kubernetes_namespace"] target_label = "namespace" } rule { source_labels = ["__meta_kubernetes_pod_name"] target_label = "pod" } rule { source_labels = ["__meta_kubernetes_pod_container_name"] target_label = "container" } } loki.source.file "kubernetes_pods" { targets = discovery.relabel.kubernetes_pods.output forward_to = [loki.process.kubernetes_pods.receiver] file_match { enabled = true } legacy_positions_file = "/tmp/positions.yaml" } loki.write "default" { endpoint { url = "http://loki.observability.svc.cluster.local:3100/loki/api/v1/push" } external_labels = {} }