0
votes

A Jobber Docker container (running periodic tasks) outputs on stdout, which is captured by Filebeat (with Docker containers autodiscovery flag on) and then sent to Logstash (within an ELK stack) or to Elasticsearch directly.

Now on Kibana, the document looks as such:

@timestamp  Jan 20, 2020 @ 20:15:07.752
...
agent.type  filebeat
container.image.name    jobber_jobber
...
message {
          "job": {
                    "command":"curl http://my.service/run","name":"myperiodictask",
                    "status":"Good",
                    "time":"0 */5 * * * *"
          },
          "startTime":1579540500,
          "stdout":"{\"startDate\":\"2020-01-20T16:35:00.000Z\",\"endDate\":\"2020-01-20T17:00:00.000Z\",\"zipped\":true,\"size\":3397}",
          "succeeded":true,
          "user":"jobberuser",
          "version":"1.4"
        }
...

Note: above 'message' field is a simple string reflecting a json object; above displayed format is for clearer readability.

My goal is to be able to request Elastic on the message fields, so I can filter by Jobber tasks for instance.

How can I make that happen ? I know Filebeat uses plugins and the container tags to apply this or that filter: are there any for Jobber? If not, how to do this?

Even better would be to be able to exploit the fields of the Jobber task result (under the 'stdout' field)! Could you please direct me to ways to implement that?

1

1 Answers

0
votes

Filebeat provides processors to handle such tasks.

Below's a configuration to handle the needs "Decode the json in the 'message' field", "Decode the json in the 'stdout' within" (both using the decode_json_fields processor), and other Jobber-related needs.

Note that given example filter the events going through Filebeat by a 'custom-tag' label given to the Docker container hosting the Jobber process. The docker.container.labels.custom-tag: jobber condition should be replaced according to your usecase.

filebeat.yml:

processors:

# === Jobber events processing ===
- if:
    equals:
      docker.container.labels.custom-tag: jobber
  then:
    # Drop Jobber events which are not job results
    - drop_event:
        when:
          not:
            regexp:
              message: "{.*"
    # Json-decode event's message part
    - decode_json_fields:
        when:
          regexp:
            message: "{.*"
        fields: ["message"]
        target: "jobbertask"
    # Json-decode message's stdout part
    - decode_json_fields:
        when:
          has_fields: ["jobbertask.stdout"]
        fields: ["jobbertask.stdout"]
        target: "jobbertask.result"
    # Drop event's decoded fields
    - drop_fields:
        fields: ["message"]
    - drop_fields:
        when:
          has_fields: ["jobbertask.stdout"]
        fields: ["jobbertask.stdout"]

The decoded fields are placed in the "jobbertask" field. This is to avoid index-mapping collision on the root fields. Feel free to replace "jobbertask" by any other field name, keeping care of mapping collisions.

In my case, this works whether Filebeat addresses the events to Logstash or to Elasticsearch directly.