{{- if .Values.logIngest.enabled }} apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: {{ .Release.Name }}-opentelemetry-collector namespace: {{ .Release.Namespace }} spec: mode: sidecar image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:latest serviceAccount: "{{ .Release.Name }}-otel-collector" volumeMounts: - name: app-logs mountPath: {{ .Values.logIngest.logPath }} securityContext: allowPrivilegeEscalation: true privileged: true runAsUser: 0 runAsGroup: 0 env: - name: KUBE_META_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: KUBE_META_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: KUBE_META_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: KUBE_META_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: KUBE_META_POD_UID valueFrom: fieldRef: fieldPath: metadata.uid - name: KUBE_META_OBJECT_NAME valueFrom: fieldRef: fieldPath: metadata.labels['app.kubernetes.io/instance'] config: receivers: filelog: include: - {{ .Values.logIngest.logPathPattern }} start_at: beginning include_file_path: false include_file_name: false operators: [] # Add container logs receiver for stdout k8s_cluster: auth_type: serviceAccount namespaces: [{{ .Release.Namespace }}] processors: resource: attributes: - action: insert key: k8s.node.name value: ${KUBE_META_NODE_NAME} - action: insert key: k8s.pod.name value: ${KUBE_META_POD_NAME} - action: insert key: k8s.pod.ip value: ${KUBE_META_POD_IP} - action: insert key: k8s.pod.uid value: ${KUBE_META_POD_UID} - action: insert key: k8s.namespace.name value: ${KUBE_META_NAMESPACE} - action: insert key: k8s.deployment.name value: ${KUBE_META_OBJECT_NAME} transform: log_statements: - context: log statements: # Set Grafana queryable labels - set(resource.attributes["service_name"], "central-storage") - set(resource.attributes["environment"], "{{ .Values.global.environment | default .Release.Namespace }}") - set(resource.attributes["pod_name"], resource.attributes["k8s.pod.name"]) - set(resource.attributes["pod_ip"], resource.attributes["k8s.pod.ip"]) # Keep application for backward compatibility - set(resource.attributes["application"], "central-storage") # Set additional kubernetes labels - set(resource.attributes["kubernetes_node_name"], resource.attributes["k8s.node.name"]) - set(resource.attributes["kubernetes_pod_name"], resource.attributes["k8s.pod.name"]) - set(resource.attributes["kubernetes_pod_ip"], resource.attributes["k8s.pod.ip"]) - set(resource.attributes["kubernetes_deployment_name"], resource.attributes["k8s.deployment.name"]) - set(resource.attributes["kubernetes_namespace"], resource.attributes["k8s.namespace.name"]) # Parse and enrich log body - set(resource.attributes["body_json"], ParseJSON(log.body)) - set(resource.attributes["body_json"]["kubernetes"]["pod"], resource.attributes["k8s.pod.name"]) - set(resource.attributes["body_json"]["kubernetes"]["namespace"], resource.attributes["k8s.namespace.name"]) - set(resource.attributes["body_json"]["kubernetes"]["pod_ip"], resource.attributes["k8s.pod.ip"]) - set(resource.attributes["body_json"]["kubernetes"]["pod_uid"], resource.attributes["k8s.pod.uid"]) - set(resource.attributes["body_json"]["kubernetes"]["deployment"], resource.attributes["k8s.deployment.name"]) - set(resource.attributes["body_json"]["kubernetes"]["node"], resource.attributes["k8s.node.name"]) - set(resource.attributes["body_json"]["kubernetes"]["namespace"], resource.attributes["k8s.namespace.name"]) - set(log.body, resource.attributes["body_json"]) - delete_key(resource.attributes, "body_json") batch: send_batch_size: 1 timeout: 1s exporters: otlphttp/logs: endpoint: {{ .Values.logIngest.lokiEndpoint }}/otlp tls: insecure: true headers: X-Scope-OrgID: "central-storage" service: telemetry: logs: level: info pipelines: logs: receivers: [filelog, k8s_cluster] # Use both filelog and k8s_cluster receivers processors: [resource, transform, batch] exporters: [otlphttp/logs] {{- end }}