Skip to content

Conversation

mergify[bot]
Copy link
Contributor

@mergify mergify bot commented Sep 19, 2025

Proposed commit message

This commit implements the use of `--directory` argument when calling `journalctl`, thus allowing it to watch for new files in the folder.

This is implemented by calling `os.Stat` on the path and checking if it is a folder, if so, then `--directory` is used instead of `--file`.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have made corresponding change to the default configuration files
  • I have added tests that prove my fix is effective or that my feature works
  • I have added an entry in CHANGELOG.next.asciidoc or CHANGELOG-developer.next.asciidoc.

## Disruptive User Impact
## Author's Checklist

How to test this PR locally

Testing in Kubernetes to ingest node logs

  1. Start a Kind cluster

  2. Deploy the Elastic Stack, make sure it will be accessible from inside the Kind cluster
    I use my own fork of elastic-package to bind on all interfaces.

  3. Build Filebeat docker image

    DEV=true SNAPSHOT=true EXTERNAL=true PACKAGES="docker" PLATFORMS=linux/amd64 mage -v package
    
  4. Load the image into your Kind cluster

    kind load docker-image docker.elastic.co/beats/filebeat-oss:9.2.0-SNAPSHOT
    
  5. Deploy Filebeat reading from /run/log/journal
    Note that the journald configuration points to the folder /run/log/journal

    - type: journald
      id: node-logs
      paths:
        - /run/log/journal
    filebeat-kubernetes.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: filebeat
      namespace: kube-system
      labels:
        k8s-app: filebeat
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: filebeat
      labels:
        k8s-app: filebeat
    rules:
    - apiGroups: [""] # "" indicates the core API group
      resources:
      - namespaces
      - pods
      - nodes
      verbs:
      - get
      - watch
      - list
    - apiGroups: ["apps"]
      resources:
        - replicasets
      verbs: ["get", "list", "watch"]
    - apiGroups: ["batch"]
      resources:
        - jobs
      verbs: ["get", "list", "watch"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: filebeat
      # should be the namespace where filebeat is running
      namespace: kube-system
      labels:
        k8s-app: filebeat
    rules:
      - apiGroups:
          - coordination.k8s.io
        resources:
          - leases
        verbs: ["get", "create", "update"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: filebeat-kubeadm-config
      namespace: kube-system
      labels:
        k8s-app: filebeat
    rules:
      - apiGroups: [""]
        resources:
          - configmaps
        resourceNames:
          - kubeadm-config
        verbs: ["get"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: filebeat
    subjects:
    - kind: ServiceAccount
      name: filebeat
      namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: filebeat
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: filebeat
      namespace: kube-system
    subjects:
      - kind: ServiceAccount
        name: filebeat
        namespace: kube-system
    roleRef:
      kind: Role
      name: filebeat
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: filebeat-kubeadm-config
      namespace: kube-system
    subjects:
      - kind: ServiceAccount
        name: filebeat
        namespace: kube-system
    roleRef:
      kind: Role
      name: filebeat-kubeadm-config
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: filebeat-config
      namespace: kube-system
      labels:
        k8s-app: filebeat
    data:
      filebeat.yml: |-
        filebeat.inputs:
        - type: journald
          id: node-logs
          paths:
            - /run/log/journal
    
        processors:
          - add_host_metadata:
    
        output.elasticsearch:
          hosts: ['https://172.17.0.1:9200'] # host machine
          username: elastic
          password: changeme
          ssl.verification_mode: none
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: filebeat
      namespace: kube-system
      labels:
        k8s-app: filebeat
    spec:
      selector:
        matchLabels:
          k8s-app: filebeat
      template:
        metadata:
          labels:
            k8s-app: filebeat
        spec:
          serviceAccountName: filebeat
          terminationGracePeriodSeconds: 30
          hostNetwork: true
          dnsPolicy: ClusterFirstWithHostNet
          containers:
          - name: filebeat
            image: docker.elastic.co/beats/filebeat-oss:9.2.0-SNAPSHOT
            args: [
              "-c", "/etc/filebeat.yml",
              "-e",
            ]
            env:
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            securityContext:
              runAsUser: 0
              # If using Red Hat OpenShift uncomment this:
              #privileged: true
            resources:
              limits:
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 100Mi
            volumeMounts:
            - name: config
              mountPath: /etc/filebeat.yml
              readOnly: true
              subPath: filebeat.yml
            - name: data
              mountPath: /usr/share/filebeat/data
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
            - name: varlog
              mountPath: /var/log
              readOnly: true
            - name: runlogjournal
              mountPath: /run/log/journal
              readOnly: true
          volumes:
          - name: config
            configMap:
              defaultMode: 0640
              name: filebeat-config
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
          - name: varlog
            hostPath:
              path: /var/log
          # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
          - name: data
            hostPath:
              # When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
              path: /var/lib/filebeat-data
              type: DirectoryOrCreate
          - name: runlogjournal
            hostPath:
              path: /run/log/journal
    ---
    

    kubectl apply -f filebeat-kubernetes.yaml
    
  6. Ensure the logs are coming in in Kibana

    1. Create a dataview to show logs from filebeat-9.2.0
    2. Go to Discover and check for the logs

Using journal files

  1. Decompress all journal?.journal.gz files and prepare the destination folder

    cd filebeat/input/journald/testdata
    gunzip journal?.journal.gz
    mkdir /tmp/journald
    
  2. Start Filebeat with the following configuration

    filebeat.yaml

    filebeat.inputs:
      - type: journald
        id: foo
        paths:
          - /tmp/journal
    
    queue.mem:
      flush.timeout: 0
    
    output.discard:
      enabled: true
    
    http.enabled: true
    http.host: localhost
    http.port: 5066
    

    You might see some erros in the logs because `/tmp/journald` is empty, ignore them.
  3. Start monitoring the stats endpoint for published events

    watch -c 'curl -s http://localhost:5066/stats|jq '.filebeat.events''
    

    You will see a JSON like:

    {
      "active": 0,
      "added": 0,
      "done": 0
    }    

    Keep an eye in the done counter, that's the number of published events.

  4. Move the first journal file to /tmp/journald and wait until all events are published

    mv journal1.journal /tmp/journal
    

    Wait untill the done counter is 10.

  5. Repeat the process for the other two journal files
    There are 10 entries in each file, so at the end of the test, there should be 30 published files.

    mv journal2.journal /tmp/journal
    # Wait 'done' to be 20
    mv journal3.journal /tmp/journal
    # Wait 'done' to be 30
    

Related issues

## Use cases
## Screenshots
## Logs


This is an automatic backport of pull request #46682 done by [Mergify](https://mergify.com).

This commit implements the use of `--directory` argument when calling
`journalctl`, thus allowing it to watch for new files in the folder.

This is implemented by calling `os.Stat` on the path and checking if
it is a folder, if so, then `--directory` is used instead of `--file`.

(cherry picked from commit 8af95b5)
@mergify mergify bot added the backport label Sep 19, 2025
@mergify mergify bot requested a review from a team as a code owner September 19, 2025 15:24
@mergify mergify bot removed the request for review from a team September 19, 2025 15:24
@mergify mergify bot requested review from faec and leehinman September 19, 2025 15:24
@mergify mergify bot added the backport label Sep 19, 2025
@botelastic botelastic bot added the needs_team Indicates that the issue/PR needs a Team:* label label Sep 19, 2025
@github-actions github-actions bot added Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team bugfix labels Sep 19, 2025
@elasticmachine
Copy link
Collaborator

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

@botelastic botelastic bot removed the needs_team Indicates that the issue/PR needs a Team:* label label Sep 19, 2025
Copy link
Contributor Author

mergify bot commented Sep 22, 2025

This pull request has not been merged yet. Could you please review and merge it @belimawr? 🙏

@belimawr belimawr merged commit 18ae95e into 8.18 Sep 22, 2025
36 checks passed
@belimawr belimawr deleted the mergify/bp/8.18/pr-46682 branch September 22, 2025 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport bugfix Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants