apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: alloy
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "0"
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://grafana.github.io/helm-charts
    chart: alloy
    targetRevision: "1.10.0"
    helm:
      values: |
        alloy:
          configMap:
            content: |-
              // Discover Kubernetes pods
              discovery.kubernetes "pods" {
                role = "pod"
              }

              // Relabel pods to intelligently map existing Kubernetes labels to service/component
              discovery.relabel "pods" {
                targets = discovery.kubernetes.pods.targets

                // Create service label - try multiple sources in priority order
                rule {
                  source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
                  regex = "(.+)"
                  replacement = "${1}"
                  target_label = "service"
                }
                // 2. Second priority: app label
                rule {
                  source_labels = ["__meta_kubernetes_pod_label_app", "service"]
                  regex = "^(.+);$"
                  replacement = "${1}"
                  target_label = "service"
                }
                // 3. Third priority: extract from pod name (remove hash suffix)
                rule {
                  source_labels = ["__meta_kubernetes_pod_name", "service"]
                  regex = "^([a-z0-9-]+?)(?:-[a-f0-9]{5,10})?;$"
                  replacement = "${1}"
                  target_label = "service"
                }

                // Create component label from app.kubernetes.io/component or component label
                rule {
                  source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_component"]
                  regex = ".+"
                  target_label = "component"
                }
                rule {
                  source_labels = ["__meta_kubernetes_pod_label_component"]
                  regex = ".+"
                  target_label = "component"
                }

                // Drop pods that we still can't identify
                rule {
                  source_labels = ["service"]
                  regex = "^$"
                  action = "drop"
                }

                // Map standard Kubernetes metadata to Loki labels
                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"
                }
              }

              // Filter out noisy fsnotify/inotify errors from Loki and ArgoCD
              loki.process "filter" {
                forward_to = [loki.write.loki.receiver]

                stage.drop {
                  expression    = ".*fsnotify.*|.*too many open files.*|.*inotify.*"
                  drop_counter_reason = "inotify_noise"
                }
              }

              // Collect logs from Kubernetes pods using the Kubernetes API
              loki.source.kubernetes "pods" {
                targets    = discovery.relabel.pods.output
                forward_to = [loki.process.filter.receiver]
              }

              // Write logs to Loki
              loki.write "loki" {
                endpoint {
                  url = "http://loki.metrics.svc.cluster.local:3100/loki/api/v1/push"
                }
              }
  destination:
    server: https://kubernetes.default.svc
    namespace: metrics
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
