Scripts and Templates

You can use scripts and templates when defining a watch. Scripts and templates can reference elements in the watch execution context, including the watch payload. The execution context defines variables you can use in a script and parameter placeholders you can use in a template. Transforms also update the contents of the watch payload.

Watcher uses the Elasticsearch script infrastructure, which supports inline, indexed, and file-based scripts. Scripts and templates are compiled and cached by Elasticsearch to optimize recurring execution. Autoloading is also supported. For more information, see Scripting in the Elasticsearch Reference.

Watch Execution Context

The following snippet shows the basic elements in a watch’s execution context:

{
  "ctx" : {
    "metadata" : { ... }, 
    "payload" : { ... }, 
    "watch_id" : "<id>", 
    "execution_time" : "20150220T00:00:10Z", 
    "trigger" : { 
      "triggered_time" : "20150220T00:00:10Z",
      "scheduled_time" : "20150220T00:00:00Z"
    },
    "vars" : { ... } 
}

Any static metadata specified in the watch definition.

The current watch payload.

The id of the executing watch.

A timestamp that shows when the watch execution started.

Information about the trigger event. For a schedule trigger, this consists of the triggered_time (when the watch was triggered) and the scheduled_time (when the watch was scheduled to be triggered).

Dynamic variables that can be set and accessed by different constructs during the execution. These variables are scoped to a single execution (i.e they’re not persisted and can’t be used between different executions of the same watch)

Using Scripts

You can use scripts to define conditions and transforms. The default scripting language is groovy.

Scripts can reference any of the values in the watch execution context or values explicitly passed through script parameters.

For example, if the context metadata contains a color field, "metadata" : {"color": "red"}, you can access its value with the variable ctx.metadata.color. If you pass in a color parameter as part of the condition or transform definition, "params" : {"color": "red"}, you access its value with the variable color.

Using Templates

You use templates to define dynamic content for a watch. At execution time, templates pull in data from the watch’s execution context. For example, you could use a template to populate the subject field for an email action with data stored in the watch payload. Templates can also access values explicitly passed through template parameters.

Watcher supports templates in a variety of places:

  • The http input supports templates in the path, params, headers and body fields.
  • The email action supports templates in the from, reply_to, priority, to, cc, bcc, subject, body.text and body.html fields.
  • The webhook action supports templates in the path, params, headers and body fields.

You specify templates using the Mustache scripting language.

While Elasticsearch supports Mustache out of the box, Watcher ships with its own version registered under xmustache. This is because the default Mustache implementation in Elasticsearch 1.5 lacks array/list access support. xmustache adds this support to enable easy array access. For example, to refer to the source of the third search hit in the payload use {{ctx.payload.hits.hits.2._source}}.

When this feature is available in Elasticsearch, we expect to remove xmustache from Watcher and use the version that ships with Elasticsearch.

For example, if the context metadata contains a color field, you can access its value with the expression {{ctx.metadata.color}}. If the context payload contains the results of a search, you could access the source of the 3rd search hit in the payload with the following expression {{ctx.payload.hits.hits.2._source}}.

If you pass in a parameter as part of the input or action definition, you can reference the parameter by name. For example, the following snippet defines and references the color parameter.

{
  "actions" : {
    "email_notification" : {
      "email" : {
        "subject" : {
          "inline" : "{{color}} alert",
          "params" : {
            "color" : "red"
          }
        }
      }
    }
  }
}

Inline Templates and Scripts

To define an inline template or script, you simply specify it directly in the value of a field. For example, the following snippet configures the subject of the email action using an inline template that references the color value in the context metadata.

"actions" : {
  "email_notification" : {
     "email" : {
       "subject" : "{{ctx.metadata.color}} alert"
     }
   }
  }
}

For a script, you simply specify the inline script as the value of the script field. For example:

"condition" : {
  "script" : "return true"
}

You can also explicitly specify the inline type by using a formal object definition as the field value. For example:

"actions" : {
  "email_notification" : {
    "email" : {
      "subject" : {
         "inline" : "{{ctx.metadata.color}} alert"
      }
    }
  }
}

The formal object definition for a script would be:

"condition" : {
  "script" : {
    "inline": "return true"
  }
}

Indexed Templates and Scripts

If you index your templates and scripts, you can reference them by id.

To reference an indexed script or template, you use the formal object definition and specify its id in the id field. For example, the following snippet references the email_notification_subject template.

{
  ...
  "actions" : {
    "email_notification" : {
      "email" : {
        "subject" : {
          "id" : "email_notification_subject",
          "params" : {
            "color" : "red"
          }
        }
      }
    }
  }
}

File-based Templates and Scripts

If you store templates or scripts in the $ES_HOME/config/scripts directory, you can reference them by name. Template files must be saved with the extension .mustache. Script files must be saved with the appropriate file extension, such as .groovy.

The config/scripts directory is scanned periodically for changes. New and changed templates and scripts are reloaded and deleted templates and scripts are removed from the preloaded scripts cache. For more information, see Automatic Script Reloading in the Elasticsearch Reference.

To reference a file-based index or script, you use the formal object definition and specify its name in the file field. For example, the following snippet references the script file threshold_hits.groovy.

"condition" : {
    "script" : {
      "file" : "threshold_hits",
      "params" : {
        "threshold" : 0
      }
    }
  }