How to transform a json object into flat fields in watcher?

we got a watcher to capture certain payload in json format. for example

"host":
"myserver": {
    "jvm": {
                {
                  "version": "14.0.1",
                  "vm_name": "OpenJDK",
                  "vm_vendor": "IBM"
                }
     }
}

these vary per payload. Hhow to make this into key-value fields, so each field can be indexed into another index as key-value fields. So the final outcome we looking for is as a single Event as below

2020-09-20 10:00:00 host.myserver.jvm.version: 14.0.1  host.myserver.jvm.vm_name: OpenJDK   host.myserver.jvm.vm_vendor: IBM

Any generic transform to achieve such JSON parsing to flat fields?

Take this as a starting point

GET _cat/indices

POST _watcher/watch/_execute
{
  "watch": {
    "trigger": {
      "schedule": {
        "interval": "10h"
      }
    },
    "input": {
      "simple": {
        "foo": "bar",
        "host": {
          "foo" : "bar",
          "myserver": {
            "jvm": {
              "version": "14.0.1",
              "vm_name": "OpenJDK",
              "vm_vendor": "IBM"
            }
          }
        }
      }
    },
    "transform" : {
      "script" : {
        "lang" : "painless",
        "source" : """
void flatten(def map, def key, def value) {
  if (value instanceof String) {
    map[key] = value;
  } else if (value instanceof Map) {
    for (def entry : value.entrySet()) {
      def prefix = key != "" ? key + "." + entry.getKey() : entry.getKey();
      flatten(map, prefix, entry.getValue())
    }
  }
}
def map = [:];
flatten(map, "", ctx.payload);
return map;
        """
      }
    },
    "actions": {
      "logme": {
        "logging": {
          "text": "{{ctx.payload}}"
        }
      }
    }
  }
}

Note that the transform method does not take care of arrays yet, but should just give you a start.

--Alex

1 Like