Skip to content

[Filebeat Hints Autodiscover] Fail to merge processors from hints with default_config's processors  #36838

Closed
@MichaelKatsoulis

Description

Description

In Filebeat deployed in a Kubernetes cluster a user can select autodiscovery with kubernetes provider instead of using filebeat.inputs. This can be done by commenting the filebeat.inputs block and uncommenting the filebeat.autodiscover one as described in

# To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
.
If hints are enabled, in the hints.default_config: block the user specifies which input will be used for each discovered resource and can additionally set processors, parsers and paths. As an example:

  filebeat.yml: |-
    # filebeat.inputs:
    # - type: container
    #   paths:
    #     - /var/log/containers/*.log
    #   processors:
    #     - add_kubernetes_metadata:
    #         host: ${NODE_NAME}
    #         matchers:
    #         - logs_path:
    #             logs_path: "/var/log/containers/"

    To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
    filebeat.autodiscover:
     providers:
       - type: kubernetes
         node: ${NODE_NAME}
         hints.enabled: true
         hints.default_config:
           type: container
           paths:
             - /var/log/containers/*${data.kubernetes.container.id}.log
           processors:
            - add_tags:
                tags: [web]
                target: "environment"

User can then deploy a pod and annotate it with hints to include additional processors like this :

cat redis-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: redis
  annotations: 
    co.elastic.logs/json.add_error_key: "true"
    co.elastic.logs/processors.add_fields.target: "project"
    co.elastic.logs/processors.add_fields.fields.name: "myproject"
spec:
  containers:
  - name: redis
    image: redis:5.0.4
    command:
      - redis-server
      - "/redis-master/redis.conf"

Expected behaviour

The expected behaviour would be that for Redis discovered pod the container input will be used. Its configuration would include both the processors (add_tags from default_config and add_fields from hints). It should look like this (for processors alone):

processors:
    - add_tags:
        tags: [web]
        target: "environment"
    - add_fields:
        target: project
        fields:
           name: myproject

Result

Instead filebeat logs an error:

{"log.level":"error","@timestamp":"2023-10-13T14:01:46.466Z","log.logger":"autodiscover.cfgfile","log.origin":{"file.name":"cfgfile/list.go","file.line":138},"message":"Error creating runner from config: each processor must have exactly one action, but found 2 actions (add_fields,add_tags)","service.name":"filebeat","ecs.version":"1.6.0"}

Both processors don't work and Redis logs are not collected.

Reason

The reason for that error is that the merged processors configuration looks like this:

processors:
    - add_tags:
        tags: [web]
        target: "environment"
      add_fields:
	      target: project
	      fields:
	        name: myproject

add_tags and add_fields are grouped together under the same processor index. add_fields is not appended even though the processors is a list. This happens in this code line where the hints config is merged to default_config. The Merge method used by default does not append elements to lists. This is explained in this issue

Solution

Instead of the merge method, MergeWithOpts should be used with the option AppendValues.
config.MergeWithOpts(tempCfg, ucfg.AppendValues).
That way processors or parsers or paths found in the hints will be appended in the existing ones from default_config.
This has been tested to work properly.

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions