discovery.kubernetes "pods" { role = "pod" selectors { role = "pod" field = "spec.nodeName=" + sys.env("HOSTNAME") } } discovery.relabel "pod_logs" { targets = discovery.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" } rule { source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"] regex = "(.+)" target_label = "app" } rule { source_labels = [ "__meta_kubernetes_pod_label_app_kubernetes_io_name", "__meta_kubernetes_pod_label_app", ] separator = ";" regex = "^;(.+)$" replacement = "$1" target_label = "app" } rule { source_labels = [ "__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name", ] separator = "/" replacement = "/var/log/pods/*$1/*.log" target_label = "__path__" } rule { source_labels = ["__meta_kubernetes_pod_container_id"] regex = `^(\S+):\/\/.+$` replacement = "$1" target_label = "container_runtime" } } local.file_match "pod_logs" { path_targets = discovery.relabel.pod_logs.output } loki.source.file "pod_logs" { targets = local.file_match.pod_logs.targets forward_to = [loki.process.pod_logs.receiver] } loki.process "pod_logs" { stage.match { selector = `{container_runtime=~"containerd|cri-o"}` stage.cri {} } stage.match { selector = `{container_runtime="docker"}` stage.docker {} } stage.replace { expression = `(?i)"(?:authorization|bearer|jwt|password|passwd|client[_-]?secret)"\s*:\s*"([^"\\]*(?:\\.[^"\\]*)*)"` replace = "[REDACTED]" } stage.replace { expression = `(?i)(?:authorization\s*[:=]\s*)(?:bearer\s+)?([A-Za-z0-9._~+/=-]+)` replace = "[REDACTED]" } stage.replace { expression = `(?i)\bbearer\s+([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+){0,2})` replace = "[REDACTED]" } stage.replace { expression = `(?i)(?:password|passwd|client[_-]?secret)\s*[:=]\s*([^\s"'{},]+)` replace = "[REDACTED]" } stage.json { expressions = { level = "level", } } stage.labels { values = { level = "", } } stage.match { selector = `{level!~"(?i)^(trace|debug|info|warn|warning|error|fatal|panic)$"}` stage.label_drop { values = ["level"] } } stage.static_labels { values = { cluster = "home", } } stage.label_keep { values = ["cluster", "namespace", "app", "pod", "container", "level"] } forward_to = [loki.write.local.receiver] } loki.write "local" { endpoint { url = "http://loki.observability.svc.cluster.local:3100/loki/api/v1/push" batch_size = "256KiB" batch_wait = "1s" remote_timeout = "10s" min_backoff_period = "500ms" max_backoff_period = "30s" max_backoff_retries = 10 } } otelcol.receiver.otlp "traces" { grpc { endpoint = "0.0.0.0:4317" } output { traces = [otelcol.processor.k8sattributes.traces.input] } } otelcol.processor.k8sattributes "traces" { auth_type = "serviceAccount" extract { deployment_name_from_replicaset = false metadata = [ "k8s.namespace.name", "k8s.deployment.name", "k8s.node.name", "k8s.pod.name", "k8s.pod.uid", "k8s.pod.start_time", "k8s.container.name", ] } pod_association { source { from = "resource_attribute" name = "k8s.pod.uid" } } pod_association { source { from = "resource_attribute" name = "k8s.pod.ip" } } pod_association { source { from = "connection" } } output { traces = [otelcol.processor.batch.traces.input] } } otelcol.processor.batch "traces" { timeout = "1s" send_batch_size = 512 send_batch_max_size = 1024 output { traces = [otelcol.exporter.otlp.tempo.input] } } otelcol.exporter.otlp "tempo" { client { endpoint = "tempo.observability.svc.cluster.local:4317" tls { insecure = true } } retry_on_failure { enabled = true initial_interval = "1s" max_interval = "15s" max_elapsed_time = "5m" } sending_queue { enabled = true queue_size = 256 num_consumers = 2 sizer = "requests" block_on_overflow = true } }