Mustache template to access timestamp field

I want to create a watch that generates an action for a certain event, but I want to format the output using a mustache template.

In the output I want to be able to say when each event happened, e.g.

{{#ctx.payload.hits.hits}}
  At {{_source.@timestamp}} this happened.
{{/ctx.payload.hits.hits}}

I am using an online mustache template tester to help write the template, but this tester doesn't seem to be able to access fields that start with an @.

Will this work in elasticsearch? If not, how would I get the field value since its key starts with @

Thanks

From what I can tell Mustache won't work with fields that start with an @ sign. (Probably because Javascript identifiers can't start with an @). You could set up a scripted field timestamp that just returns the timestamp. Or you could change your documents so that the timestamp field doesn't start with an @ sign.

Thank you. When you add scripted fields it seems to add them as an array so I had to access the value as if it were an array in mustache.

So in my watcher JSON in input.search.request

"script_fields" : {
  "tstamp": {
    "script" : "doc['@timestamp']"
  }
}

Then in actions the mustache template would look like this:

{{#ctx.payload.hits.hits}}
  At {{fields.tstamp.0}} this happened
{{/ctx.payload.hits.hits}}

That is odd that the tstamp comes as an array. Sounds like maybe a watcher bug? Pretty sure that scripted fields don't work like that in other contexts. Glad that you got it working.

I am getting arrays from scripted fields using DevTools > Console

PUT test-script-fields
{
  "mappings": {
    "_doc" : {
      "properties": {
        "orig_field": { "type" : "keyword" }
      }
    }
  }
}
POST test-script-fields/_doc
{
  "orig_field": "value"
}
GET test-script-fields/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "new_field": {
      "script": "doc['orig_field']"
    }
  }
}

Response

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "test-script-fields",
        "_type": "_doc",
        "_id": "lJ_QEGUBKMz4hZe4_pnw",
        "_score": 1,
        "fields": {
          "new_field": [
            "value"
          ]
        }
      }
    ]
  }
}

Thanks for the knowledge.

1 Like

Using a script field means that Elasticsearch has to load the doc values of all the hits of a query (which might be millions) into memory.

Also, your snippet seems to work for me, this sample watch

POST _xpack/watcher/watch/_execute
{
  "watch": {
    "trigger": {
      "schedule": {
        "interval": "10h"
      }
    },
    "input": {
      "simple": {
        "hits": {
          "hits": [
            {
              "_source": {
                "@timestamp": "123"
              }
            }
          ]
        }
      }
    },
    "actions": {
      "logme": {
        "logging": {
          "text": "{{#ctx.payload.hits.hits}} At {{_source.@timestamp}} this happened. {{/ctx.payload.hits.hits}}"
        }
      }
    }
  }
}

logs

[2018-08-07T08:34:02,287][INFO ][o.e.x.w.a.l.ExecutableLoggingAction] [DWc9wWT]  At 123 this happened.

so maybe the issue is somewhere else? If you share your whole watch and the output of the execute watch API in a gist, that would make it easier to help.

1 Like

Thank you @spinscale, this worked for me as well. I had not tried accessing @timestamp from within the watch, I had only tried it with the javascript version of mustache, which is what seems to have the problem accessing fields with @ in them.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.