Skip to content

[kubernetes#container_logs] allow to edit ID and add docs on how to ingest rotated logs - #15793

Merged
AndersonQ merged 4 commits into
elastic:mainfrom
AndersonQ:15792-kubernetes-docs-rotated-logs
Dec 1, 2025
Merged

[kubernetes#container_logs] allow to edit ID and add docs on how to ingest rotated logs#15793
AndersonQ merged 4 commits into
elastic:mainfrom
AndersonQ:15792-kubernetes-docs-rotated-logs

Conversation

@AndersonQ

@AndersonQ AndersonQ commented Oct 29, 2025

Copy link
Copy Markdown
Member

Proposed commit message

    [kubernetes] update container logs
    
     - Allow to configure input ID.
     - Update container logs docs to include how to ingest rotated log files, including GZIP-compressed files.

Checklist

  • [ ] I have reviewed tips for building integrations and this pull request is aligned with them.
  • [ ] I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • [ ] I have verified that Kibana version constraints are current according to guidelines.
  • [ ] I have verified that any added dashboard complies with Kibana's Dashboard good practices

How to test this PR locally

  • Create an elastic stack
  • setup a kind cluster
kind create cluster
  • deploy the agent to the cluster following the instructions in kibana. If you see the error InvalidImageName, check here to see hot to fix it
  • add the k8s integration from the fleet UI
  • start some flog containers:
kubectl apply -f ./flog.yaml
flog.yaml:
apiVersion: batch/v1
kind: Job
metadata:
  name: flog-log-generator
spec:
  template:
    spec:
      containers:
        - name: flog-unstructured-cont-rot
          image: mingrammer/flog
          #          too small "-d" won't give kubelet time to rotate the files
          args: ["-t", "stdout", "-d", "1us", "-l"]
        - name: crashloop-1
          image: busybox
          imagePullPolicy: IfNotPresent
          command: ["sh", "-c", "echo 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vel illum dolore eu feugiat nulla facilisis at' >&2; sleep 1; exit 1"]
      restartPolicy: OnFailure
  backoffLimit: 10
  • ensure the logs are being ingested. Use filter log.file.path : *flog*
  • build, then install the integration
cd packages/kubernetes
elastic-package build -v
elastic-package install -v
  • upgrade the integration
  • check all is normal, no configuration has changed
  • follow the docs to ingest the rotated logs
  • check:
    • there is a spike in ingested logs:
Screenshot from 2025-11-11 11-53-33
  • check the crashloop-1 container logs to see it reingested the logs using the new path
Screenshot from 2025-11-11 11-53-11
  • check the rotated logs were ingested. Use the following filters log.file.path : *flog*log.* and log.file.path : *flog*log.*.gz:
Screenshot from 2025-11-11 12-19-58 Screenshot from 2025-11-11 12-20-10
  • get an agent diagnostic and inspect filestream configuration components/filestream-default/beat-rendered-config.yml to ensure the ID has the correct pattern and the path is correct:
      id: kubernetes-container-logs-83c0d508-bd6b-45c5-88f7-9f08a56a3563-kube-controller-manager
      index: logs-kubernetes.container_logs-default
      parsers:
        - container:
            format: auto
            stream: all
      paths:
        - /var/log/pods/kube-system_kube-controller-manager-kind-control-plane_83c0d508-bd6b-45c5-88f7-9f08a56a3563/kube-controller-manager/*.log*

Disruptive User Impact

When enabling the ingestion of rotated logs on an existing deployment, it cause a one-time re-ingestion of the logs.

The input ID when using autodiscover is now scoped by container name, instead of container id. It's done to avoid data duplication as explained below.

Context: K8s logging architecture

Logs are written to:

/var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/<restart_count>.log # Active log file
/var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/<restart_count>.log.TIMRESTAMP` # 1st rotation, plain file
/var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/<restart_count>.log.TIMRESTAMP.gz` # subsequenmtt rotations, gziped

Legacy symlinked path:

/var/log/containers/<pod_name>_<namespace>_<container_name>-<container_id>.log -> /var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/<restart_count>.log

Thus during a container restart, a CrashLoopBackoff, it's possible to have 2
containers with the same name, but different IDs. The container which just crashed
and is being removed and the new container being created.

Just for the example, lets consider:

container name: foo
container id 1: id-1
container id 2: id-2

pod name: pod
namespace: ns
pod uid: uid

This leads to the following log files and symlinks during the transition:

/var/log/pods/ns_pod_uid/foo/0.log
/var/log/pods/ns_pod_uid/foo/1.log

/var/log/containers/pod_ns_foo-id-1.log -> /var/log/pods/ns_pod_uid/foo/0.log
/var/log/containers/pod_ns_foo-id-2.log -> /var/log/pods/ns_pod_uid/foo/1.log

k8s log collection

1 filestream input per container. Input ID pattern: kubernetes-container-logs-${data.kubernetes.pod.name}-${data.kubernetes.container.id}

Thus, for each container id, one input is created.

Rotated logs

Rotated logs are scoped by container name, and restart counter, not container ID. (/var/log/pods/<pod_name><pod_uid>/<container_name>/<restart_count>.log)
To collect rotated logs, the following wildcard would be used:

/var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/*.log.*
id: kubernetes-container-logs-${kubernetes.pod.name}-${kubernetes.container.id}
paths:
  - /var/log/containers/*<container_id>.log
  - /var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/*.log.*

for the example above, during the container restart, there would be 2 inputs created:

id: kubernetes-container-logs-pod-id-1
paths:
  - /var/log/containers/*id-1.log
  - /var/log/pods/ns_pod_uid/foo/*.log.*
id: kubernetes-container-logs-pod-id-2
paths:
  - /var/log/containers/*id-2.log
  - /var/log/pods/ns_pod_uid/foo/*.log.*

Both inputs harvest /var/log/pods/ns_pod_uid/foo/*.log.*, duplicating the data.

Therefore, the ID pattern must be scoped by container name.

Related issues

Screenshots

@AndersonQ AndersonQ self-assigned this Oct 29, 2025
@AndersonQ AndersonQ added Integration:kubernetes Kubernetes Team:Elastic-Agent-Data-Plane Agent Data Plane team [elastic/elastic-agent-data-plane] labels Oct 29, 2025
@andrewkroh andrewkroh added the documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. label Oct 29, 2025
@AndersonQ
AndersonQ force-pushed the 15792-kubernetes-docs-rotated-logs branch 3 times, most recently from d3ed0e9 to 1ac8fcc Compare November 5, 2025 13:24
@AndersonQ AndersonQ changed the title [kubernetes] wip update docs Nov 5, 2025
@AndersonQ
AndersonQ force-pushed the 15792-kubernetes-docs-rotated-logs branch from 1ac8fcc to a0c7b79 Compare November 5, 2025 13:25
@AndersonQ
AndersonQ marked this pull request as ready for review November 5, 2025 13:26
@AndersonQ
AndersonQ requested review from a team as code owners November 5, 2025 13:26
@elasticmachine

Copy link
Copy Markdown

Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane)

@AndersonQ
AndersonQ force-pushed the 15792-kubernetes-docs-rotated-logs branch from a0c7b79 to 3464497 Compare November 5, 2025 13:32
@pierrehilbert pierrehilbert added Team:obs-ds-hosted-services Observability Hosted Services team [elastic/obs-ds-hosted-services] Team:Ecosystem Packages Ecosystem team [elastic/ecosystem] labels Nov 5, 2025
@elasticmachine

Copy link
Copy Markdown

Pinging @elastic/ecosystem (Team:Ecosystem)

@elastic-vault-github-plugin-prod

elastic-vault-github-plugin-prod Bot commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

Comment thread packages/kubernetes/_dev/build/docs/container-logs.md Outdated
@AndersonQ
AndersonQ marked this pull request as draft November 10, 2025 13:10
@AndersonQ
AndersonQ force-pushed the 15792-kubernetes-docs-rotated-logs branch 3 times, most recently from b12d5d7 to bf7e169 Compare November 11, 2025 11:40
@AndersonQ
AndersonQ marked this pull request as ready for review November 11, 2025 11:40
@AndersonQ AndersonQ changed the title [kubernetes] Update container logs docs to include how to ingest rotated logs Nov 11, 2025
@AndersonQ AndersonQ changed the title [kubernetes#container_logs] allow to edit DI and add docs on how to ingest rotated logs Nov 11, 2025
@AndersonQ
AndersonQ requested review from a team and faec and removed request for a team November 11, 2025 11:50
@AndersonQ
AndersonQ requested a review from leehinman November 11, 2025 11:50
 - Allow to configure input ID.
 - Update container logs docs to include how to ingest rotated log files, including GZIP-compressed files.
@AndersonQ
AndersonQ force-pushed the 15792-kubernetes-docs-rotated-logs branch from bf7e169 to 41cb1f3 Compare November 14, 2025 08:51

@faec faec left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nit, otherwise looks good

Comment thread packages/kubernetes/_dev/build/docs/container-logs.md

The integration can monitor and ingest rotated Kubernetes container logs, including
on-the-fly decompression of GZIP archives. To enable this:
- change the _ID_ to `kubernetes-container-logs-${kubernetes.pod.uid}-${kubernetes.container.name}`

@gizas gizas Nov 18, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- change the _ID_ to `kubernetes-container-logs-${kubernetes.pod.uid}-${kubernetes.container.name}`
- change the `ID` to `kubernetes-container-logs-${kubernetes.pod.uid}-${kubernetes.container.name}`

@gizas gizas Nov 18, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are refering to the ID field right? ID the unique identifier for the input. So the ID can b misleading

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean if it's ID instead of ID? Or that ID isn't clear enough?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe the _ ID_ can be misleading. minor

default: kubernetes-container-logs-${kubernetes.pod.name}-${kubernetes.container.id}
title: ID
description: >
ID the unique identifier for the input.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can add here in the description the new ID: /var/log/pods/${kubernetes.namespace}_${kubernetes.pod.name}_${kubernetes.pod.uid}/${kubernetes.container.name}/*.log* that should be added here in case gzip_experimental: true or a link to this doc

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in fb0869f

Comment on lines +15 to +21
The integration can monitor and ingest rotated Kubernetes container logs, including
on-the-fly decompression of GZIP archives. To enable this:
- change the _ID_ to `kubernetes-container-logs-${kubernetes.pod.uid}-${kubernetes.container.name}`
- add `gzip_experimental: true` under _Advanced options > Custom configurations_. Refer to
{{ url "filebeat-input-filestream" "filestream documentation on reading GZIP files" }} for details.
- set the path to `/var/log/pods/${kubernetes.namespace}_${kubernetes.pod.name}_${kubernetes.pod.uid}/${kubernetes.container.name}/*.log*`. Refer to the official
[Kubernetes documentation on log rotation](https://kubernetes.io/docs/concepts/cluster-administration/logging/#log-rotation) for details on the log rotation mechanism and file naming convention.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect more possible values for this? Wondering if this could be a boolean option, that changes the defaults.

I guess we are not making this the default to avoid breaking changes? Or this is not available in all clusters?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is we do not have to know if there is a custom configuration, if the user changed the defaults. The toggle would override everything, regardless if it's the default or not. That's why I did not use a toggle

Comment thread packages/kubernetes/data_stream/container_logs/manifest.yml
@andrewkroh andrewkroh added the enhancement New feature or request label Nov 25, 2025
@AndersonQ
AndersonQ requested a review from gizas December 1, 2025 13:42
@AndersonQ

Copy link
Copy Markdown
Member Author

@gizas, I made the changes you requested

@jsoriano I made the changes you requested, if you wanna review again, please do so :)

@elasticmachine

Copy link
Copy Markdown

💚 Build Succeeded

History

cc @AndersonQ

@AndersonQ
AndersonQ merged commit 7f5376e into elastic:main Dec 1, 2025
8 checks passed
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Package kubernetes - 1.82.0 containing this change is available at https://epr.elastic.co/package/kubernetes/1.82.0/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. enhancement New feature or request Integration:kubernetes Kubernetes Team:Ecosystem Packages Ecosystem team [elastic/ecosystem] Team:Elastic-Agent-Data-Plane Agent Data Plane team [elastic/elastic-agent-data-plane] Team:obs-ds-hosted-services Observability Hosted Services team [elastic/obs-ds-hosted-services]

7 participants