[[customizing-watches]] == Customizing Watches Now that you've seen how to set up simple watches to <> and <>, let's take a closer look at how you can customize a watch by modifying its <>, <>, <>, and <>. [[changing-inputs]] === Changing Inputs Watcher supports three types of inputs <>, <>, and <>. [[loading-static-data]] ==== Loading Static Data with the Simple Input To load static data into the watch payload for testing purposes, you can use the <> input. For example, the following input stores three fields in the payload: [source,js] -------------------------------------------------- "input" : { "simple" : { "color" : "red", "status" : "error", "count" : 3 } } -------------------------------------------------- [[loading-search-results]] ==== Loading Search Results with the Search Input To load search results into the watch payload, you use the `search` input. In addition to simple match queries like the one shown in the <> guide, you can use the full Elasticsearch query language. A <> input contains a `request` object that specifies the indices you want to search, the {ref}/search-request-search-type.html[search type], and the search request body. The `body` field of a search input is the same as the body of an Elasticsearch `_search` request. NOTE: The default search type is {ref}/search-request-search-type.html#count[`count`], which differs from the Elasticsearch default of `query_then_fetch`. //////////// For example, the following search input searches the watch history indices for watch records whose execution_duration exceeded 2.5 seconds. [source,js] -------------------------------------------------- "input" : { "search": { "request": { "indices": [ ".watch_history*" ], "body": { "size" : 0, "query" : { "filtered": { "query" : { "match_all" : { } }, "filter": { "range": { "result.execution_duration": { "gt": 2500 } } } } } } } } }, -------------------------------------------------- //////////// [[loading-http-data]] ==== Loading a Webserver Response with the HTTP Input To query a webserver and load the response into the watch payload, you use the `http` input. In addition to calling Elasticsearch APIs as shown in the <> guide, you can submit requests to any webserver that returns a response in JSON. //////////// For example, the following input gets excerpts for all of the questions posted to Stack Overflow during the month of May, 2015 that were tagged with `elasticsearch`. [source,js] -------------------------------------------------- "input" : { "http" : { "request" : { "host" : "api.stackexchange.com", "port" : 80, "path" : "https://api.stackexchange.com/2.2/search/excerpts", "params" : { <1> "fromdate" : 1430438400, "todate" : 1433030400, "order" : "desc", "sort" : "activity", "tagged" : "elasticsearch", "site" : "stackoverflow" } } } } -------------------------------------------------- <1> The query string parameters are passed to the server using a `params` field, they are not included as part of the path. //////////// [[changing-conditions]] === Changing Conditions Watcher supports four types of conditions <>, <>, <>, and <>. The first two are pretty self-explanatory--they are shortcuts for setting a watch's condition to `true` or `false`. The `compare` condition enables you to perform simple comparisons against values in the Watch payload. While you can also do this with a `script` condition, with `compare` you can define inline comparisons without having to enable dynamic scripting. You can use the `script` condition to perform more complex evaluations of the data in the watch payload. For example, the following compare condition checks to see if the 'search' input returned any hits: [source,js] -------------------------------------------------- "condition" : { "compare" : { "ctx.payload.hits.total" : { "gt" : 0 }} }, -------------------------------------------------- //////////// The following script condition checks Stack Overflow excerpts loaded by an 'http' input to see if there are unanswered questions that have a question_score of 3 or higher. [source,js] -------------------------------------------------- "condition" : { "script" : "def items = ctx.payload.items; def createResult = {if (it.question_score.value >= 3 && it.has_accepted_answer.value == false) {return true}}; items.each(createResult)" } -------------------------------------------------- //////////// [[using-transforms]] === Using Transforms Watcher supports three types of transforms <>, <> and <>. A `search` transform replaces the existing payload with the results of a new search request. You can use `script` transforms to modify the existing payload. A `chain` transform enables you to perform a series of `search` and `script` transforms. //////////// For example, the following chain transform performs a 'query_then_fetch' search to load the source of the watch records that have an 'execution_duration' of more than 2.5 seconds. A script transform then extracts selected information from the search results and updates the watch payload. [source,js] -------------------------------------------------- "transform" : { "chain" : [ { "search" : { "search_type" : "query_then_fetch", "indices" : [ ".watch_history*" ], "body" : { "query" : { "filtered": { "query" : { "match_all" : { } }, "filter": { "range": { "result.execution_duration": { "gt": 2500 } } } } } } } }, { "script" : "def records = ctx.payload.hits.hits; def result = [ ]; def createResult = {if (!it) { result = '0'} else {result << it._source.result.execution_duration.value}}; records.each(createResult); return result" } ] }, -------------------------------------------------- //////////// [[customizing-actions]] === Customizing Actions Watcher supports four types of actions <>, <>, <>, and <>. To use the `email` action, you need to <> in `elasticsearch.yml` that Watcher can use to send email. Your custom email messages can be plain text or styled using HTML. You can include information from the watch payload using <>, as well as attach the entire watch payload to the message. For example, the following email action uses a template in the subject line and attaches the payload data to the message. [source,js] -------------------------------------------------- "actions" : { "send_email" : { "email" : { "to" : "@", "subject" : "Watcher Notification", "body" : "{{ctx.payload.hits.total}} watches took more than 2.5 seconds to execute.", "attach_data" : true } } } -------------------------------------------------- The `index` action enables you to load data from the watch payload into an Elasticsearch index. The entire payload can be indexed as a single document, or you can use a transform to populate a `_doc` field with an array of objects that are indexed as separate documents. //////////// For example, the following index action indexes each of the excerpts extracted from Stack Overflow as a separate document. [source,js] -------------------------------------------------- "actions" : { "index_payload" : { "transform": { ... }, "index" : { "index" : "questions", "doc_type" : "stackoverflow-excerpt" } } } -------------------------------------------------- //////////// The `logging` action enables you to add entries to the Elasticsearch logs, which is useful during development and testing. For example, the following logging action logs the number of watches that took longer than 2.5 seconds to run. [source,js] -------------------------------------------------- "actions" : { "log" : { "logging" : { "text" : "{{ctx.payload.hits.total}} watches took more than 2.5 seconds to execute" } } } -------------------------------------------------- The `webhook` action enables you to submit a request to any external webservice. For example, the following webhook action creates a Pagerduty trigger event. [source,js] -------------------------------------------------- "actions" : { "send_trigger" : { "throttle_period" : "5m", "webhook" : { "method" : "POST", "host" : "https://events.pagerduty.com", "port" : 443, "path": ":/generic/2010-04-15/create_event.json}", "body" : "{ \"service_key\": \"e93facc04764012d7bfb002500d5d1a6\", \"incident_key\": \"long_watches\", \"event_type\": \"trigger\", \"description\": \"{{ctx.payload.hits.total}} watches took more than 2.5 seconds to execute\", \"client\": \"Watcher\" }" "headers": {"Content-type": "application/json"} } } } --------------------------------------------------