sensu-plugins-elasticsearch 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -2
- data/bin/check-es-query-average.rb +281 -0
- data/lib/sensu-plugins-elasticsearch/elasticsearch-query.rb +27 -2
- data/lib/sensu-plugins-elasticsearch/version.rb +2 -2
- metadata +16 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37833026481f5b5a0dd6494267bd542efaecc44d
|
4
|
+
data.tar.gz: b8271c8cf122df1714b6531ce7ba3635fcc0f256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e639765580a65cb627e99f8b7bb89482284488115e40678b4dd05112fde3aea98392beef4bb5ef534bea8e1f958e65d9a86495e69e7dd62b9083217a94af9ffd
|
7
|
+
data.tar.gz: 86a3c8224667571da1e7aa2ddd7484fcbddf0fa14d7655786d6c703418b016007d03d27adf4b16006e7217bf757e4b175925b9331d6335bdb132ca2327cad742
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
#Change Log
|
1
|
+
# Change Log
|
2
2
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
3
3
|
|
4
4
|
This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
|
5
5
|
|
6
6
|
## [Unreleased]
|
7
7
|
|
8
|
+
## [1.5.0] - 2017-07-26
|
9
|
+
### Added
|
10
|
+
- check-es-query-average.rb: check of average result by field (@ilavender)
|
11
|
+
|
8
12
|
## [1.4.1] - 2017-07-13
|
9
13
|
### Fixed
|
10
14
|
- use timestamp_field from config for sorting in Kibana (@osgida)
|
@@ -164,7 +168,8 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
164
168
|
### Added
|
165
169
|
- initial release
|
166
170
|
|
167
|
-
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.
|
171
|
+
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.5.0...HEAD
|
172
|
+
[1.5.0]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.4.1...1.5.0
|
168
173
|
[1.4.1]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.4.0...1.4.1
|
169
174
|
[1.4.0]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.3.1...1.4.0
|
170
175
|
[1.3.1]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.3.0...1.3.1
|
@@ -0,0 +1,281 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-es-query
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin checks an ElasticSearch query.
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
# gem: elasticsearch
|
17
|
+
# gem: aws_es_transport
|
18
|
+
#
|
19
|
+
# USAGE:
|
20
|
+
# This example checks that the average of the field "serve_time" in logs matching a query of
|
21
|
+
# anything (*) at the host elasticsearch.service.consul for the past 90 minutes
|
22
|
+
# will warn if above 120ms and go critical if the result average is above 250ms
|
23
|
+
# check-es-query-average.rb -h elasticsearch.service.consul -q "*"
|
24
|
+
# --types special_type -d 'logging-%Y.%m.%d' --minutes-previous 90 -p 9200 -c 0.250 -w 0.120 -a serve_time
|
25
|
+
#
|
26
|
+
# NOTES:
|
27
|
+
#
|
28
|
+
# LICENSE:
|
29
|
+
# Itamar Lavender <itamar.lavender@gmail.com>
|
30
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
31
|
+
# for details.
|
32
|
+
#
|
33
|
+
|
34
|
+
require 'sensu-plugin/check/cli'
|
35
|
+
require 'elasticsearch'
|
36
|
+
require 'time'
|
37
|
+
require 'uri'
|
38
|
+
require 'aws_es_transport'
|
39
|
+
require 'sensu-plugins-elasticsearch'
|
40
|
+
|
41
|
+
#
|
42
|
+
# ES Query Count
|
43
|
+
#
|
44
|
+
class ESQueryAverage < Sensu::Plugin::Check::CLI
|
45
|
+
include ElasticsearchCommon
|
46
|
+
|
47
|
+
option :index,
|
48
|
+
description: 'Elasticsearch indices to query.
|
49
|
+
Comma-separated list of index names to search.
|
50
|
+
Use `_all` or empty string to perform the operation on all indices.
|
51
|
+
Accepts wildcards',
|
52
|
+
short: '-i INDEX',
|
53
|
+
long: '--indices INDEX'
|
54
|
+
|
55
|
+
option :transport,
|
56
|
+
long: '--transport TRANSPORT',
|
57
|
+
description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
|
58
|
+
|
59
|
+
option :region,
|
60
|
+
long: '--region REGION',
|
61
|
+
description: 'Region (necessary for AWS Transport)'
|
62
|
+
|
63
|
+
option :types,
|
64
|
+
description: 'Elasticsearch types to limit searches to, comma separated list.',
|
65
|
+
long: '--types TYPES'
|
66
|
+
|
67
|
+
option :timestamp_field,
|
68
|
+
description: 'Field to use instead of @timestamp for query.',
|
69
|
+
long: '--timestamp-field FIELD_NAME',
|
70
|
+
default: '@timestamp'
|
71
|
+
|
72
|
+
option :offset,
|
73
|
+
description: 'Seconds before offset to end @timestamp against query.',
|
74
|
+
long: '--offset OFFSET',
|
75
|
+
proc: proc(&:to_i),
|
76
|
+
default: 0
|
77
|
+
|
78
|
+
option :ignore_unavailable,
|
79
|
+
description: 'Ignore unavailable indices.',
|
80
|
+
long: '--ignore-unavailable',
|
81
|
+
boolean: true,
|
82
|
+
default: true
|
83
|
+
|
84
|
+
option :minutes_previous,
|
85
|
+
description: 'Minutes before offset to check @timestamp against query.',
|
86
|
+
long: '--minutes-previous MINUTES_PREVIOUS',
|
87
|
+
proc: proc(&:to_i),
|
88
|
+
default: 0
|
89
|
+
|
90
|
+
option :hours_previous,
|
91
|
+
description: 'Hours before offset to check @timestamp against query.',
|
92
|
+
long: '--hours-previous HOURS_PREVIOUS',
|
93
|
+
proc: proc(&:to_i),
|
94
|
+
default: 0
|
95
|
+
|
96
|
+
option :days_previous,
|
97
|
+
description: 'Days before offset to check @timestamp against query.',
|
98
|
+
long: '--days-previous DAYS_PREVIOUS',
|
99
|
+
proc: proc(&:to_i),
|
100
|
+
default: 0
|
101
|
+
|
102
|
+
option :weeks_previous,
|
103
|
+
description: 'Weeks before offset to check @timestamp against query.',
|
104
|
+
long: '--weeks-previous WEEKS_PREVIOUS',
|
105
|
+
proc: proc(&:to_i),
|
106
|
+
default: 0
|
107
|
+
|
108
|
+
option :months_previous,
|
109
|
+
description: 'Months before offset to check @timestamp against query.',
|
110
|
+
long: '--months-previous MONTHS_PREVIOUS',
|
111
|
+
proc: proc(&:to_i),
|
112
|
+
default: 0
|
113
|
+
|
114
|
+
option :date_index,
|
115
|
+
description: 'Elasticsearch time based index.
|
116
|
+
Accepts format from http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime',
|
117
|
+
short: '-d DATE_INDEX',
|
118
|
+
long: '--date-index DATE_INDEX'
|
119
|
+
|
120
|
+
option :date_repeat_daily,
|
121
|
+
description: 'Elasticsearch date based index repeats daily.',
|
122
|
+
long: '--repeat-daily',
|
123
|
+
boolean: true,
|
124
|
+
default: true
|
125
|
+
|
126
|
+
option :date_repeat_hourly,
|
127
|
+
description: 'Elasticsearch date based index repeats hourly.',
|
128
|
+
long: '--repeat-hourly',
|
129
|
+
boolean: true,
|
130
|
+
default: false
|
131
|
+
|
132
|
+
option :search_field,
|
133
|
+
description: 'The Elasticsearch document field to search for your query string.',
|
134
|
+
short: '-f FIELD',
|
135
|
+
long: '--field FIELD',
|
136
|
+
required: false,
|
137
|
+
default: 'message'
|
138
|
+
|
139
|
+
option :query,
|
140
|
+
description: 'Elasticsearch query',
|
141
|
+
short: '-q QUERY',
|
142
|
+
long: '--query QUERY',
|
143
|
+
required: false
|
144
|
+
|
145
|
+
option :aggr,
|
146
|
+
description: 'Elasticsearch query aggr',
|
147
|
+
long: '--aggr',
|
148
|
+
boolean: true,
|
149
|
+
required: false,
|
150
|
+
default: true
|
151
|
+
|
152
|
+
option :aggr_field,
|
153
|
+
description: 'Elasticsearch query field to aggregate and average from',
|
154
|
+
short: '-a FIELD',
|
155
|
+
long: '--aggr-field FIELD',
|
156
|
+
required: true
|
157
|
+
|
158
|
+
option :host,
|
159
|
+
description: 'Elasticsearch host',
|
160
|
+
short: '-h HOST',
|
161
|
+
long: '--host HOST',
|
162
|
+
default: 'localhost'
|
163
|
+
|
164
|
+
option :port,
|
165
|
+
description: 'Elasticsearch port',
|
166
|
+
short: '-p PORT',
|
167
|
+
long: '--port PORT',
|
168
|
+
proc: proc(&:to_i),
|
169
|
+
default: 9200
|
170
|
+
|
171
|
+
option :scheme,
|
172
|
+
description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
|
173
|
+
short: '-s SCHEME',
|
174
|
+
long: '--scheme SCHEME'
|
175
|
+
|
176
|
+
option :password,
|
177
|
+
description: 'Elasticsearch connection password',
|
178
|
+
short: '-P PASSWORD',
|
179
|
+
long: '--password PASSWORD'
|
180
|
+
|
181
|
+
option :user,
|
182
|
+
description: 'Elasticsearch connection user',
|
183
|
+
short: '-u USER',
|
184
|
+
long: '--user USER'
|
185
|
+
|
186
|
+
option :timeout,
|
187
|
+
description: 'Elasticsearch query timeout in seconds',
|
188
|
+
short: '-t TIMEOUT',
|
189
|
+
long: '--timeout TIMEOUT',
|
190
|
+
proc: proc(&:to_i),
|
191
|
+
default: 30
|
192
|
+
|
193
|
+
option :warn,
|
194
|
+
short: '-w N',
|
195
|
+
long: '--warn N',
|
196
|
+
description: 'Result average WARNING threshold',
|
197
|
+
proc: proc(&:to_f),
|
198
|
+
default: 0
|
199
|
+
|
200
|
+
option :crit,
|
201
|
+
short: '-c N',
|
202
|
+
long: '--crit N',
|
203
|
+
description: 'Result average CRITICAL threshold',
|
204
|
+
proc: proc(&:to_f),
|
205
|
+
default: 0
|
206
|
+
|
207
|
+
option :invert,
|
208
|
+
long: '--invert',
|
209
|
+
description: 'Invert thresholds',
|
210
|
+
boolean: true
|
211
|
+
|
212
|
+
option :kibana_url,
|
213
|
+
long: '--kibana-url KIBANA_URL',
|
214
|
+
description: 'Kibana URL query prefix that will be in critical / warning response output.'
|
215
|
+
|
216
|
+
def kibana_info
|
217
|
+
kibana_date_format = '%Y-%m-%dT%H:%M:%S.%LZ'
|
218
|
+
unless config[:kibana_url].nil?
|
219
|
+
index = config[:index]
|
220
|
+
unless config[:date_index].nil?
|
221
|
+
date_index_partition = config[:date_index].split('%')
|
222
|
+
index = "[#{date_index_partition.first}]" \
|
223
|
+
"#{date_index_partition[1..-1].join.sub('Y', 'YYYY').sub('y', 'YY').sub('m', 'MM').sub('d', 'DD').sub('j', 'DDDD').sub('H', 'hh')}"
|
224
|
+
end
|
225
|
+
end_time = Time.now.utc.to_i
|
226
|
+
start_time = end_time
|
227
|
+
if config[:minutes_previous] != 0
|
228
|
+
start_time -= (config[:minutes_previous] * 60)
|
229
|
+
end
|
230
|
+
if config[:hours_previous] != 0
|
231
|
+
start_time -= (config[:hours_previous] * 60 * 60)
|
232
|
+
end
|
233
|
+
if config[:days_previous] != 0
|
234
|
+
start_time -= (config[:days_previous] * 60 * 60 * 24)
|
235
|
+
end
|
236
|
+
if config[:weeks_previous] != 0
|
237
|
+
start_time -= (config[:weeks_previous] * 60 * 60 * 24 * 7)
|
238
|
+
end
|
239
|
+
if config[:months_previous] != 0
|
240
|
+
start_time -= (config[:months_previous] * 60 * 60 * 24 * 31)
|
241
|
+
end
|
242
|
+
"Kibana logs: #{config[:kibana_url]}/#/discover?_g=" \
|
243
|
+
"(refreshInterval:(display:Off,section:0,value:0),time:(from:'" \
|
244
|
+
"#{URI.escape(Time.at(start_time).utc.strftime kibana_date_format)}',mode:absolute,to:'" \
|
245
|
+
"#{URI.escape(Time.at(end_time).utc.strftime kibana_date_format)}'))&_a=(columns:!(_source),index:" \
|
246
|
+
"#{URI.escape(index)},interval:auto,query:(query_string:(analyze_wildcard:!t,query:'" \
|
247
|
+
"#{URI.escape(config[:query])}')),sort:!('@timestamp',desc))&dummy"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def run
|
252
|
+
response = client.search(build_request_options)
|
253
|
+
if config[:invert]
|
254
|
+
if response['aggregations']['average']['value'] < config[:crit]
|
255
|
+
critical "Query average (#{response['aggregations']['average']['value']}) was below critical threshold. #{kibana_info}"
|
256
|
+
elsif response['aggregations']['average']['value'] < config[:warn]
|
257
|
+
warning "Query average (#{response['aggregations']['average']['value']}) was below warning threshold. #{kibana_info}"
|
258
|
+
else
|
259
|
+
ok "Query average (#{response['aggregations']['average']['value']}) was ok"
|
260
|
+
end
|
261
|
+
elsif response['aggregations']['average']['value'] > config[:crit]
|
262
|
+
critical "Query average (#{response['aggregations']['average']['value']}) was above critical threshold. #{kibana_info}"
|
263
|
+
elsif response['aggregations']['average']['value'] > config[:warn]
|
264
|
+
warning "Query average (#{response['aggregations']['average']['value']}) was above warning threshold. #{kibana_info}"
|
265
|
+
else
|
266
|
+
ok "Query average (#{response['aggregations']['average']['value']}) was ok"
|
267
|
+
end
|
268
|
+
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
269
|
+
if config[:invert]
|
270
|
+
if response['aggregations']['average']['value'] < config[:crit]
|
271
|
+
critical "Query average (#{response['aggregations']['average']['value']}) was below critical threshold. #{kibana_info}"
|
272
|
+
elsif response['aggregations']['average']['value'] < config[:warn]
|
273
|
+
warning "Query average (#{response['aggregations']['average']['value']}) was below warning threshold. #{kibana_info}"
|
274
|
+
else
|
275
|
+
ok "Query average (#{response['aggregations']['average']['value']}) was ok"
|
276
|
+
end
|
277
|
+
else
|
278
|
+
ok 'No results found, average was below thresholds'
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
@@ -78,6 +78,31 @@ module ElasticsearchQuery
|
|
78
78
|
|
79
79
|
if !config[:body].nil?
|
80
80
|
options[:body] = config[:body]
|
81
|
+
elsif config[:aggr] == true
|
82
|
+
es_date_start = es_date_math_string end_time
|
83
|
+
options[:size] = 0
|
84
|
+
options[:body] = {
|
85
|
+
'query' => {
|
86
|
+
'bool' => {
|
87
|
+
'must' => [{
|
88
|
+
'query_string' => {
|
89
|
+
'default_field' => config[:search_field],
|
90
|
+
'query' => config[:query]
|
91
|
+
}
|
92
|
+
}, {
|
93
|
+
'range' => {
|
94
|
+
config[:timestamp_field] => {
|
95
|
+
'gt' => es_date_start,
|
96
|
+
'lt' => end_time.strftime('%Y-%m-%dT%H:%M:%S')
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}]
|
100
|
+
}
|
101
|
+
},
|
102
|
+
'aggregations' => {
|
103
|
+
'average' => { 'avg' => { 'field' => config[:aggr_field] } }
|
104
|
+
}
|
105
|
+
}
|
81
106
|
else
|
82
107
|
es_date_start = es_date_math_string end_time
|
83
108
|
unless es_date_start.nil?
|
@@ -114,7 +139,7 @@ module ElasticsearchQuery
|
|
114
139
|
config[:days_previous] == 0 && \
|
115
140
|
config[:weeks_previous] == 0 && \
|
116
141
|
config[:months_previous] == 0
|
117
|
-
|
142
|
+
nil
|
118
143
|
else
|
119
144
|
es_math = "#{end_time.strftime '%Y-%m-%dT%H:%M:%S'}||"
|
120
145
|
es_math += "-#{config[:minutes_previous]}m" if config[:minutes_previous] != 0
|
@@ -122,7 +147,7 @@ module ElasticsearchQuery
|
|
122
147
|
es_math += "-#{config[:days_previous]}d" if config[:days_previous] != 0
|
123
148
|
es_math += "-#{config[:weeks_previous]}w" if config[:weeks_previous] != 0
|
124
149
|
es_math += "-#{config[:months_previous]}M" if config[:months_previous] != 0
|
125
|
-
|
150
|
+
es_math
|
126
151
|
end
|
127
152
|
end
|
128
153
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu Plugins and contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -224,22 +224,23 @@ description: |-
|
|
224
224
|
service health and metrics for cluster, node, and more.
|
225
225
|
email: "<sensu-users@googlegroups.com>"
|
226
226
|
executables:
|
227
|
-
- check-es-
|
228
|
-
-
|
227
|
+
- check-es-query-ratio.rb
|
228
|
+
- metrics-es-node.rb
|
229
|
+
- metrics-es-cluster.rb
|
230
|
+
- check-es-query-exists.rb
|
231
|
+
- handler-es-delete-indices.rb
|
232
|
+
- check-es-indices-sizes.rb
|
229
233
|
- check-es-cluster-status.rb
|
234
|
+
- check-es-cluster-health.rb
|
230
235
|
- check-es-file-descriptors.rb
|
231
|
-
- check-es-heap.rb
|
232
236
|
- check-es-indexes.rb
|
233
|
-
- check-es-indices-sizes.rb
|
234
|
-
- check-es-node-status.rb
|
235
237
|
- check-es-query-count.rb
|
236
|
-
- check-es-
|
237
|
-
- check-es-
|
238
|
-
- check-es-
|
239
|
-
-
|
240
|
-
- metrics-es-cluster.rb
|
238
|
+
- check-es-node-status.rb
|
239
|
+
- check-es-circuit-breakers.rb
|
240
|
+
- check-es-query-average.rb
|
241
|
+
- check-es-heap.rb
|
241
242
|
- metrics-es-node-graphite.rb
|
242
|
-
-
|
243
|
+
- check-es-shard-allocation-status.rb
|
243
244
|
extensions: []
|
244
245
|
extra_rdoc_files: []
|
245
246
|
files:
|
@@ -254,6 +255,7 @@ files:
|
|
254
255
|
- bin/check-es-indexes.rb
|
255
256
|
- bin/check-es-indices-sizes.rb
|
256
257
|
- bin/check-es-node-status.rb
|
258
|
+
- bin/check-es-query-average.rb
|
257
259
|
- bin/check-es-query-count.rb
|
258
260
|
- bin/check-es-query-exists.rb
|
259
261
|
- bin/check-es-query-ratio.rb
|
@@ -292,7 +294,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
292
294
|
version: '0'
|
293
295
|
requirements: []
|
294
296
|
rubyforge_project:
|
295
|
-
rubygems_version: 2.4.5
|
297
|
+
rubygems_version: 2.4.5.1
|
296
298
|
signing_key:
|
297
299
|
specification_version: 4
|
298
300
|
summary: Sensu plugins for elasticsearch
|