Search code examples
printflogstashlogstash-configuration

Use sprintf syntax inside logstash's sprintf syntax


For the below data structure:

{
  "sprints": [
    {
      "id": 17193,
      "name": "Sprint 12"
    },
    {
      "id": 16510,
      "name": "Sprint 11"
    }
  ],
  "velocityStatEntries": {
    "16510": {
      "estimated": {
        "value": 49
      },
      "completed": {
        "value": 36
      }
    },
    "17193": {
      "estimated": {
        "value": 52
      },
      "completed": {
        "value": 70
      }
    }
  }
}

Given this, I want to be able to produce an Elasticsearch object that's easier to handle, by adding the values of the Estimated and Completed fields to the sprints with their matching IDs.

Ideally, I would like to handle this without writing Ruby, but I am not finding a logstash-native solution that handles this scnenario.

First, I split the data on the sprints field using split, so, I only have a single sprints object, and can use [sprints][id] to know what sprint I'm processing.

Then, I have attempted to work with the mutate filter, in one of two ways: - using merge to add the [velocityStateEntries][] object to the current sprint - using add_field to add the two fields I need

Syntactically, is this possible? Ideally, I would want to be able to do a 'double substitution' of sorts, obtaining the estimated time for the current sprint something like:

add_field => {
          "estimatedTime" => "%{[velocityStatEntries][%{[sprints][id]}][estimated][value]}"
}

but this only seems to work with a hardcoded format such as "estimatedTime" => "%{[velocityStatEntries][1234][estimated][value]}"

Do I have to use the Ruby format for this?


Solution

  • For what it's worth, the Ruby solution is very simple:

      ruby {
        code => "
            sprintId = event.get('[sprints][id]');
            estimated = event.get('[velocityStatEntries]['+(sprintId).to_s+'][estimated][value]');
            completed = event.get('[velocityStatEntries]['+(sprintId).to_s+'][completed][value]');
            event.set('[sprints][estimatedUnits]', estimated);
            event.set('[sprints][completedUnits]', completed);
          "
      }