2015-07-13 06:23:07 -04:00
|
|
|
[[customizing-watches]]
|
|
|
|
== Customizing Watches
|
|
|
|
|
|
|
|
Now that you've seen how to set up simple watches to <<watch-log-data, watch your log data>>
|
|
|
|
and <<watch-cluster-status, monitor your cluster health>>, let's take a closer look at how
|
|
|
|
you can customize a watch by modifying its <<changing-inputs, inputs>>,
|
|
|
|
<<changing-conditions, conditions>>, <<using-transforms, transforms>>, and
|
|
|
|
<<customizing-actions, actions>>.
|
|
|
|
|
|
|
|
[[changing-inputs]]
|
|
|
|
=== Changing Inputs
|
|
|
|
Watcher supports three types of inputs <<loading-static-data, simple>>,
|
|
|
|
<<loading-search-results, search>>, and <<loading-http-data, http>>.
|
|
|
|
|
|
|
|
[[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-simple, simple>> 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 <<watch-log-data, Getting Started>> guide, you can use the
|
|
|
|
full Elasticsearch query language.
|
|
|
|
|
2015-09-09 21:05:21 -04:00
|
|
|
A <<input-search, search>> input contains a `request` object that specifies the indices you want to
|
2015-07-13 06:23:07 -04:00
|
|
|
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": {
|
2015-10-13 09:46:27 -04:00
|
|
|
"size" : 0,
|
2015-07-13 06:23:07 -04:00
|
|
|
"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 <<watch-cluster-status, Getting Started>>
|
|
|
|
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 <<condition-always, always>>, <<condition-never, never>>,
|
|
|
|
<<condition-compare, compare>>, and <<condition-script, script>>.
|
|
|
|
|
|
|
|
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 <<transform-search, search>>,
|
|
|
|
<<transform-script, script>> and <<transform-chain, chain>>. 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 <<actions-email, email>>,
|
|
|
|
<<actions-index, index>>, <<actions-logging, logging>>, and <<actions-webhook, webhook>>.
|
|
|
|
|
|
|
|
To use the `email` action, you need to <<email-services, configure an email account>> 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
|
|
|
|
<<templates, templates>>, 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" : "<username>@<domainname>",
|
|
|
|
"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"}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-13 09:46:27 -04:00
|
|
|
--------------------------------------------------
|