sensu-plugins-elasticsearch 0.5.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YjkwYTFiOWMzYjAzMzY0OTNiZjE5ZDZkNWY3NTliNzJiMGU2NWQ4ZQ==
5
- data.tar.gz: !binary |-
6
- OWI1ZTYzMjU5NTM1MzljZDA5NTlkOTViYThiNzBlZDY0ODQ2NTA1Yg==
2
+ SHA1:
3
+ metadata.gz: 916ac07d3bae1f72dfe1b147803712caf0051397
4
+ data.tar.gz: 49eb92c702d9b07a3f7d607f0cf412e32acf230d
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MGNhNjRjZWEzZjQ2OTBlYjI5OTJjY2Y5YmFmOTc5ZTE2YjFhODNjYjc2OWMy
10
- YmQ0OWMyZWRlMWJjYTMwODU2MzQxNjc3ZjFmYTI2ZTliODI1ODQxMmFmOGQz
11
- ZDNkNjFkNTU5OTFhYjdiNWEzYjQ2NzAyMDc2MTIwNzAxNmMwODQ=
12
- data.tar.gz: !binary |-
13
- MzYyODViMzE4OTExZGU1Y2RjMWJkY2UzNTVjMGZiY2Q1Y2QzNGJjZGY2NGQ0
14
- YTRkOWEzNTA0MThkYzE5ZDI1NjNhOWM1YjAyMGQwNzk5MjQ3ZDAzMzY0N2I1
15
- YTUzNDJhYTRmMTJlMDFiNzIzMjVmMGNkZTRjOGNlZjZkNDRiYmY=
6
+ metadata.gz: 6e1845230c4cf9911e5843f032d56bfee2cbdeccc370bf43ed5d0873665dca17b1e3c51b01416b5aac9ca008f77ae619da5804f095edbd925b76975c57c46f29
7
+ data.tar.gz: 80a2ea4fc5e0ebe877eb57f76d4510fee044fa95c1bd871c9813195109233462b890dc06957c887c197ad73fa455ee417a699b99d662f279787de8d087460f82
@@ -5,6 +5,27 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.0.0] - 2016-07-29
9
+ ### Added
10
+ - Added AWS transport gem and configuration for check-es-query-* sensu calls to use --transport=AWS (@brendangibat)
11
+ - Added a rescue for 503 on several checks: (@majormoses)
12
+ - check-es-circuit-breakers.rb
13
+ - check-es-cluster-status.rb
14
+ - check-es-file-descriptors.rb
15
+ - check-es-heap.rb
16
+ - Added option --localhost for check-es-circuit-breakers.rb to only check its local node for broken circuit (@majormoses)
17
+ - Add Ruby 2.3.0 support (@eheydrick)
18
+ - Allow using newer patch versions of elasticsearch gem within the same minor (@majormoses)
19
+ - Add check-es-cluster-health to check Elasticsearch cluster health and status (@brendangibat)
20
+ - Add check-es-indices-size to check if indicies grow above a certain size (@brendangibat)
21
+ - Add handler-es-delete-indices handler to delete indicies (@brendangibat)
22
+
23
+ ### Removed
24
+ - Ruby 1.9.3 support (@eheydrick)
25
+
26
+ ### Changed
27
+ - Update to Rubocop 0.40 and cleanup (@eheydrick)
28
+
8
29
  ## [0.5.3] - 2016-04-02
9
30
  ### Added
10
31
  - check-es-indexes (check for dup indexes) (Yieldbot)
@@ -47,6 +68,7 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
47
68
  - Update elasticsearch gem to 1.0.14
48
69
 
49
70
  ### Added
71
+ - Add check-es-cluster-health that checks health status with elasticsearch gem and can use AWS transport for checks.
50
72
  - Add check-es-circuit-breakers.rb, to alert when circuit breakers have been tripped
51
73
 
52
74
  ## [0.2.0] - 2015-10-15
@@ -85,8 +107,9 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
85
107
  ### Added
86
108
  - initial release
87
109
 
88
- [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.5.3...HEAD
89
- [0.5.3]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.4.2...0.4.3
110
+ [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/1.0.0...HEAD
111
+ [1.0.0]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.5.3...1.0.0
112
+ [0.5.3]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.4.3...0.5.3
90
113
  [0.4.3]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.4.2...0.4.3
91
114
  [0.4.2]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.4.1...0.4.2
92
115
  [0.4.1]: https://github.com/sensu-plugins/sensu-plugins-elasticsearch/compare/0.4.0...0.4.1
data/README.md CHANGED
@@ -9,15 +9,18 @@
9
9
  ## Functionality
10
10
 
11
11
  ## Files
12
- * /bin/check-es-circuit-breakers.rb
12
+ * /bin/check-es-circuit-breakers.rb
13
+ * /bin/check-es-cluster-health.rb
13
14
  * /bin/check-es-cluster-status.rb
14
15
  * /bin/check-es-file-descriptors.rb
15
16
  * /bin/check-es-heap.rb
16
17
  * /bin/check-es-indexes.rb
18
+ * /bin/check-es-indicies-sizes.rb
17
19
  * /bin/check-es-node-status.rb
18
20
  * /bin/check-es-query-count.rb
19
21
  * /bin/check-es-query-exists.rb
20
- * /bin/check-es-shard-allocation
22
+ * /bin/check-es-shard-allocation-status.rb
23
+ * /bin/handler-es-delete-indices.rb
21
24
  * /bin/metrics-es-cluster.rb
22
25
  * /bin/metrics-es-node.rb
23
26
  * /bin/metrics-es-node-graphite.rb
@@ -69,6 +69,13 @@ class ESCircuitBreaker < Sensu::Plugin::Check::CLI
69
69
  short: '-e',
70
70
  long: '--https'
71
71
 
72
+ option :localhost,
73
+ description: 'only check local node',
74
+ short: '-l',
75
+ long: '--localhost',
76
+ boolean: true,
77
+ default: false
78
+
72
79
  def get_es_resource(resource)
73
80
  headers = {}
74
81
  if config[:user] && config[:password]
@@ -88,13 +95,19 @@ class ESCircuitBreaker < Sensu::Plugin::Check::CLI
88
95
  critical 'Connection refused'
89
96
  rescue RestClient::RequestTimeout
90
97
  critical 'Connection timed out'
98
+ rescue RestClient::ServiceUnavailable
99
+ warning 'Service is unavailable'
91
100
  rescue Errno::ECONNRESET
92
101
  critical 'Connection reset by peer'
93
102
  end
94
103
 
95
104
  def breaker_status
96
105
  breakers = {}
97
- status = get_es_resource('/_nodes/stats/breaker')
106
+ status = if config[:localhost]
107
+ get_es_resource('/_nodes/_local/stats/breaker')
108
+ else
109
+ get_es_resource('/_nodes/stats/breaker')
110
+ end
98
111
  status['nodes'].each_pair do |_node, stat|
99
112
  host = stat['host']
100
113
  breakers[host] = {}
@@ -0,0 +1,118 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-es-cluster-health
4
+ #
5
+ # DESCRIPTION:
6
+ # This plugin checks the ElasticSearch cluster health and status.
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
+ # Checks against the ElasticSearch api for cluster health using the
21
+ # elasticsearch gem
22
+ #
23
+ # NOTES:
24
+ #
25
+ # LICENSE:
26
+ # Brendan Gibat <brendan.gibat@gmail.com>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ require 'sensu-plugin/check/cli'
32
+ require 'elasticsearch'
33
+ require 'aws_es_transport'
34
+ require 'sensu-plugins-elasticsearch'
35
+
36
+ #
37
+ # ES Cluster Health
38
+ #
39
+ class ESClusterHealth < Sensu::Plugin::Check::CLI
40
+ include ElasticsearchCommon
41
+
42
+ option :transport,
43
+ long: '--transport TRANSPORT',
44
+ description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
45
+
46
+ option :region,
47
+ long: '--region REGION',
48
+ description: 'Region (necessary for AWS Transport)'
49
+
50
+ option :host,
51
+ description: 'Elasticsearch host',
52
+ short: '-h HOST',
53
+ long: '--host HOST',
54
+ default: 'localhost'
55
+
56
+ option :level,
57
+ description: 'Level of detail to check returend information ("cluster", "indices", "shards").',
58
+ short: '-l LEVEL',
59
+ long: '--level LEVEL'
60
+
61
+ option :local,
62
+ description: 'Return local information, do not retrieve the state from master node.',
63
+ long: '--local',
64
+ boolean: true
65
+
66
+ option :port,
67
+ description: 'Elasticsearch port',
68
+ short: '-p PORT',
69
+ long: '--port PORT',
70
+ proc: proc(&:to_i),
71
+ default: 9200
72
+
73
+ option :scheme,
74
+ description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
75
+ short: '-s SCHEME',
76
+ long: '--scheme SCHEME'
77
+
78
+ option :password,
79
+ description: 'Elasticsearch connection password',
80
+ short: '-P PASSWORD',
81
+ long: '--password PASSWORD'
82
+
83
+ option :user,
84
+ description: 'Elasticsearch connection user',
85
+ short: '-u USER',
86
+ long: '--user USER'
87
+
88
+ option :timeout,
89
+ description: 'Elasticsearch query timeout in seconds',
90
+ short: '-t TIMEOUT',
91
+ long: '--timeout TIMEOUT',
92
+ proc: proc(&:to_i),
93
+ default: 30
94
+
95
+ def run
96
+ options = {}
97
+ unless config[:level].nil?
98
+ options[:level] = config[:level]
99
+ end
100
+ unless config[:local].nil?
101
+ options[:local] = config[:local]
102
+ end
103
+ unless config[:index].nil?
104
+ options[:index] = config[:index]
105
+ end
106
+ health = client.cluster.health options
107
+ case health['status']
108
+ when 'yellow'
109
+ warning 'Cluster state is Yellow'
110
+ when 'red'
111
+ critical 'Cluster state is Red'
112
+ when 'green'
113
+ ok
114
+ else
115
+ unknown "Cluster state is in an unknown health: #{health['status']}"
116
+ end
117
+ end
118
+ end
@@ -102,6 +102,8 @@ class ESClusterStatus < Sensu::Plugin::Check::CLI
102
102
  critical 'Connection refused'
103
103
  rescue RestClient::RequestTimeout
104
104
  critical 'Connection timed out'
105
+ rescue RestClient::ServiceUnavailable
106
+ critical 'Service is unavailable'
105
107
  rescue Errno::ECONNRESET
106
108
  critical 'Connection reset by peer'
107
109
  end
@@ -101,6 +101,8 @@ class ESFileDescriptors < Sensu::Plugin::Check::CLI
101
101
  warning 'Connection refused'
102
102
  rescue RestClient::RequestTimeout
103
103
  warning 'Connection timed out'
104
+ rescue RestClient::ServiceUnavailable
105
+ warning 'Service is unavailable'
104
106
  end
105
107
 
106
108
  def acquire_es_version
@@ -114,6 +114,8 @@ class ESHeap < Sensu::Plugin::Check::CLI
114
114
  warning 'Connection refused'
115
115
  rescue RestClient::RequestTimeout
116
116
  warning 'Connection timed out'
117
+ rescue RestClient::ServiceUnavailable
118
+ warning 'Service is unavailable'
117
119
  rescue JSON::ParserError
118
120
  warning 'Elasticsearch API returned invalid JSON'
119
121
  end
@@ -0,0 +1,185 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-es-indices-sizes.rb
4
+ #
5
+ # DESCRIPTION:
6
+ # This check sends a critical event when the indices mathing the date pattern
7
+ # are above a MB value.
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: elasticsearch
18
+ # gem: aws_es_transport
19
+ #
20
+ # USAGE:
21
+ # ./check-es-indices-sizes.rb -h localhost -p 9200 -m 155000
22
+ #
23
+ # NOTES:
24
+ #
25
+ # LICENSE:
26
+ # Brendan Leon Gibat <brendan.gibat@gmail.com>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ require 'sensu-plugin/check/cli'
32
+ require 'elasticsearch'
33
+ require 'aws_es_transport'
34
+ require 'sensu-plugins-elasticsearch'
35
+
36
+ class ESCheckIndicesSizes < Sensu::Plugin::Check::CLI
37
+ include ElasticsearchCommon
38
+
39
+ option :transport,
40
+ long: '--transport TRANSPORT',
41
+ description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
42
+
43
+ option :region,
44
+ long: '--region REGION',
45
+ description: 'Region (necessary for AWS Transport)'
46
+
47
+ option :host,
48
+ description: 'Elasticsearch host',
49
+ short: '-h HOST',
50
+ long: '--host HOST',
51
+ default: 'localhost'
52
+
53
+ option :port,
54
+ description: 'Elasticsearch port',
55
+ short: '-p PORT',
56
+ long: '--port PORT',
57
+ proc: proc(&:to_i),
58
+ default: 9200
59
+
60
+ option :scheme,
61
+ description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
62
+ short: '-s SCHEME',
63
+ long: '--scheme SCHEME'
64
+
65
+ option :password,
66
+ description: 'Elasticsearch connection password',
67
+ short: '-P PASSWORD',
68
+ long: '--password PASSWORD'
69
+
70
+ option :user,
71
+ description: 'Elasticsearch connection user',
72
+ short: '-u USER',
73
+ long: '--user USER'
74
+
75
+ option :timeout,
76
+ description: 'Elasticsearch query timeout in seconds',
77
+ short: '-t TIMEOUT',
78
+ long: '--timeout TIMEOUT',
79
+ proc: proc(&:to_i),
80
+ default: 30
81
+
82
+ option :used_percent,
83
+ description: 'Percentage of bytes to use for indices matching pattern.',
84
+ short: '-a USED_PERCENTAGE',
85
+ long: '--used-percentage USED_PERCENTAGE',
86
+ proc: proc(&:to_i),
87
+ default: 80
88
+
89
+ option :maximum_megabytes,
90
+ description: 'Maximum number megabytes for date based indices to use.',
91
+ short: '-m MAXIMUM_MEGABYTES',
92
+ long: '--maximum-megabytes MAXIMUM_MEGABYTES',
93
+ proc: proc(&:to_i),
94
+ default: 0
95
+
96
+ option :pattern_regex,
97
+ description: 'Regular expression to use for matching date based indices. Four named groups are matched, pattern, year, month, day.',
98
+ short: '-x PATTERN_REGEX',
99
+ long: '--pattern-regex PATTERN_REGEX',
100
+ default: '^(?<pattern>.*)-(?<year>\d\d\d\d)\.(?<month>\d\d?).(?<day>\d\d?)$'
101
+
102
+ def get_indices_to_delete(starting_date, total_bytes_to_delete, indices_with_sizes)
103
+ total_bytes_deleted = 0
104
+ curr_date = DateTime.now
105
+
106
+ indices_to_delete = []
107
+
108
+ # We don't delete the current day, as it is most likely being used.
109
+ while total_bytes_deleted < total_bytes_to_delete && starting_date < curr_date
110
+ same_day_indices = indices_with_sizes.values.map do |pattern|
111
+ pattern.select do |index|
112
+ index['date'] == starting_date
113
+ end
114
+ end.flatten
115
+ same_day_indices.each do |index|
116
+ if total_bytes_deleted < total_bytes_to_delete
117
+ indices_to_delete.push(index['index'])
118
+ total_bytes_deleted += index['size']
119
+ end
120
+ end
121
+ starting_date += 1
122
+ end
123
+
124
+ indices_to_delete
125
+ end
126
+
127
+ def build_indices_with_sizes
128
+ indices_fs_stats = client.indices.stats store: true
129
+ pattern_regex = Regexp.new(config[:pattern_regex])
130
+
131
+ index_with_sizes = indices_fs_stats['indices'].keys.each_with_object({}) do |key, hash|
132
+ matching_index = pattern_regex.match(key)
133
+ unless matching_index.nil?
134
+ base_pattern = matching_index[:pattern]
135
+ unless base_pattern.nil?
136
+ unless hash.include?(base_pattern)
137
+ hash[base_pattern] = []
138
+ end
139
+ index_date = DateTime.new(matching_index[:year].to_i, matching_index[:month].to_i, matching_index[:day].to_i)
140
+ hash[base_pattern].push(
141
+ size: indices_fs_stats['indices'][key]['total']['store']['size_in_bytes'].to_i,
142
+ date: index_date,
143
+ index: key
144
+ )
145
+ end
146
+ end
147
+ end
148
+
149
+ index_with_sizes
150
+ end
151
+
152
+ def run
153
+ node_fs_stats = client.nodes.stats metric: 'fs,indices'
154
+ nodes_being_used = node_fs_stats['nodes'].values.select { |node| node['indices']['store']['size_in_bytes'] > 0 }
155
+ # rubocop:disable SingleLineBlockParams
156
+ # rubocop:disable LineLength
157
+ used_in_bytes = nodes_being_used.map { |node| node['fs']['data'].map { |data| data['total_in_bytes'] - data['available_in_bytes'] }.flatten }.flatten.inject { |sum, x| sum + x }
158
+ # rubocop:enable LineLength
159
+ total_in_bytes = nodes_being_used.map { |node| node['fs']['data'].map { |data| data['total_in_bytes'] }.flatten }.flatten.inject { |sum, x| sum + x }
160
+ # rubocop:enable SingleLineBlockParams
161
+
162
+ if config[:maximum_megabytes] > 0
163
+ target_bytes_used = config[:maximum_megabytes] * 1_000_000
164
+ else
165
+ if config[:used_percent] > 100 || config[:used_percent] < 0
166
+ critical 'You can not make used-percentages greater than 100 or less than 0.'
167
+ end
168
+ target_bytes_used = (total_in_bytes.to_f * (config[:used_percent].to_f / 100.0)).to_i
169
+ end
170
+
171
+ total_bytes_to_delete = used_in_bytes - target_bytes_used
172
+ if total_bytes_to_delete <= 0
173
+ ok "Used space in bytes: #{used_in_bytes}, Total in bytes: #{total_in_bytes}"
174
+ end
175
+
176
+ indices_with_sizes = build_indices_with_sizes
177
+
178
+ oldest = indices_with_sizes.values.flatten.map { |index| index['date'] }.min
179
+ indices_to_delete = get_indices_to_delete(oldest, total_bytes_to_delete, indices_with_sizes)
180
+
181
+ critical "Not enough space, #{total_bytes_to_delete} bytes need to be deleted. Used space in bytes: " \
182
+ "#{used_in_bytes}, Total in bytes: #{total_in_bytes}. Indices to delete: " \
183
+ "#{indices_to_delete.sort.map { |i| "INDEX[#{i}]" }.join(', ')}"
184
+ end
185
+ end
@@ -14,6 +14,7 @@
14
14
  # DEPENDENCIES:
15
15
  # gem: sensu-plugin
16
16
  # gem: elasticsearch
17
+ # gem: aws_es_transport
17
18
  #
18
19
  # USAGE:
19
20
  # This example checks that the count of special_type logs matching a query of
@@ -34,10 +35,12 @@
34
35
  require 'sensu-plugin/check/cli'
35
36
  require 'elasticsearch'
36
37
  require 'time'
38
+ require 'uri'
39
+ require 'aws_es_transport'
37
40
  require 'sensu-plugins-elasticsearch'
38
41
 
39
42
  #
40
- # ES Heap
43
+ # ES Query Count
41
44
  #
42
45
  class ESQueryCount < Sensu::Plugin::Check::CLI
43
46
  include ElasticsearchCommon
@@ -50,6 +53,14 @@ class ESQueryCount < Sensu::Plugin::Check::CLI
50
53
  short: '-i INDEX',
51
54
  long: '--indices INDEX'
52
55
 
56
+ option :transport,
57
+ long: '--transport TRANSPORT',
58
+ description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
59
+
60
+ option :region,
61
+ long: '--region REGION',
62
+ description: 'Region (necessary for AWS Transport)'
63
+
53
64
  option :types,
54
65
  description: 'Elasticsearch types to limit searches to, comma separated list.',
55
66
  long: '--types TYPES'
@@ -65,6 +76,12 @@ class ESQueryCount < Sensu::Plugin::Check::CLI
65
76
  proc: proc(&:to_i),
66
77
  default: 0
67
78
 
79
+ option :ignore_unavailable,
80
+ description: 'Ignore unavailable indices.',
81
+ long: '--ignore-unavailable',
82
+ boolean: true,
83
+ default: true
84
+
68
85
  option :minutes_previous,
69
86
  description: 'Minutes before offset to check @timestamp against query.',
70
87
  long: '--minutes-previous MINUTES_PREVIOUS',
@@ -142,8 +159,7 @@ class ESQueryCount < Sensu::Plugin::Check::CLI
142
159
  option :scheme,
143
160
  description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
144
161
  short: '-s SCHEME',
145
- long: '--scheme SCHEME',
146
- default: 'https'
162
+ long: '--scheme SCHEME'
147
163
 
148
164
  option :password,
149
165
  description: 'Elasticsearch connection password',
@@ -181,31 +197,68 @@ class ESQueryCount < Sensu::Plugin::Check::CLI
181
197
  description: 'Invert thresholds',
182
198
  boolean: true
183
199
 
200
+ option :kibana_url,
201
+ long: '--kibana-url KIBANA_URL',
202
+ description: 'Kibana URL query prefix that will be in critical / warning response output.'
203
+
204
+ def kibana_info
205
+ kibana_date_format = '%Y-%m-%dT%H:%M:%S.%LZ'
206
+ unless config[:kibana_url].nil?
207
+ index = config[:index]
208
+ unless config[:date_index].nil?
209
+ date_index_partition = config[:date_index].split('%')
210
+ index = "[#{date_index_partition.first}]" \
211
+ "#{date_index_partition[1..-1].join.sub('Y', 'YYYY').sub('y', 'YY').sub('m', 'MM').sub('d', 'DD').sub('j', 'DDDD').sub('H', 'hh')}"
212
+ end
213
+ end_time = Time.now.utc.to_i
214
+ start_time = end_time
215
+ if config[:minutes_previous] != 0
216
+ start_time -= (config[:minutes_previous] * 60)
217
+ end
218
+ if config[:hours_previous] != 0
219
+ start_time -= (config[:hours_previous] * 60 * 60)
220
+ end
221
+ if config[:days_previous] != 0
222
+ start_time -= (config[:days_previous] * 60 * 60 * 24)
223
+ end
224
+ if config[:weeks_previous] != 0
225
+ start_time -= (config[:weeks_previous] * 60 * 60 * 24 * 7)
226
+ end
227
+ if config[:months_previous] != 0
228
+ start_time -= (config[:months_previous] * 60 * 60 * 24 * 7 * 31)
229
+ end
230
+ "Kibana logs: #{config[:kibana_url]}/#/discover?_g=" \
231
+ "(refreshInterval:(display:Off,section:0,value:0),time:(from:'" \
232
+ "#{URI.escape(Time.at(start_time).utc.strftime kibana_date_format)}',mode:absolute,to:'" \
233
+ "#{URI.escape(Time.at(end_time).utc.strftime kibana_date_format)}'))&_a=(columns:!(_source),index:" \
234
+ "#{URI.escape(index)},interval:auto,query:(query_string:(analyze_wildcard:!t,query:'" \
235
+ "#{URI.escape(config[:query])}')),sort:!('@timestamp',desc))&dummy"
236
+ end
237
+ end
238
+
184
239
  def run
185
240
  response = client.count(build_request_options)
186
241
  if config[:invert]
187
242
  if response['count'] < config[:crit]
188
- critical "Query count (#{response['count']}) was below critical threshold"
243
+ critical "Query count (#{response['count']}) was below critical threshold. #{kibana_info}"
189
244
  elsif response['count'] < config[:warn]
190
- warning "Query count (#{response['count']}) was below warning threshold"
245
+ warning "Query count (#{response['count']}) was below warning threshold. #{kibana_info}"
191
246
  else
192
247
  ok "Query count (#{response['count']}) was ok"
193
248
  end
249
+ elsif response['count'] > config[:crit]
250
+ critical "Query count (#{response['count']}) was above critical threshold. #{kibana_info}"
251
+ elsif response['count'] > config[:warn]
252
+ warning "Query count (#{response['count']}) was above warning threshold. #{kibana_info}"
194
253
  else
195
- if response['count'] > config[:crit] # rubocop:disable Style/IfInsideElse
196
- critical "Query count (#{response['count']}) was above critical threshold"
197
- elsif response['count'] > config[:warn]
198
- warning "Query count (#{response['count']}) was above warning threshold"
199
- else
200
- ok "Query count (#{response['count']}) was ok"
201
- end
254
+ ok "Query count (#{response['count']}) was ok"
202
255
  end
203
256
  rescue Elasticsearch::Transport::Transport::Errors::NotFound
204
257
  if config[:invert]
205
258
  if response['count'] < config[:crit]
206
- critical "Query count (#{response['count']}) was below critical threshold"
259
+ critical "Query count (#{response['count']}) was below critical threshold. #{kibana_info}"
207
260
  elsif response['count'] < config[:warn]
208
- warning "Query count (#{response['count']}) was below warning threshold"
261
+ warning "Query count (#{response['count']}) was below warning threshold. #{kibana_info}"
209
262
  else
210
263
  ok "Query count (#{response['count']}) was ok"
211
264
  end
@@ -35,10 +35,12 @@
35
35
 
36
36
  require 'sensu-plugin/check/cli'
37
37
  require 'elasticsearch'
38
+ require 'time'
39
+ require 'aws_es_transport'
38
40
  require 'sensu-plugins-elasticsearch'
39
41
 
40
42
  #
41
- # ES Heap
43
+ # ES Query Exists
42
44
  #
43
45
  class ESQueryExists < Sensu::Plugin::Check::CLI
44
46
  include ElasticsearchCommon
@@ -51,6 +53,14 @@ class ESQueryExists < Sensu::Plugin::Check::CLI
51
53
  short: '-i INDEX',
52
54
  long: '--indices INDEX'
53
55
 
56
+ option :transport,
57
+ long: '--transport TRANSPORT',
58
+ description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
59
+
60
+ option :region,
61
+ long: '--region REGION',
62
+ description: 'Region (necessary for AWS Transport)'
63
+
54
64
  option :types,
55
65
  description: 'Elasticsearch types to limit searches to, comma separated list.',
56
66
  long: '--types TYPES'
@@ -114,10 +124,9 @@ class ESQueryExists < Sensu::Plugin::Check::CLI
114
124
  boolean: true,
115
125
  default: false
116
126
 
117
- option :query,
118
- description: 'Elasticsearch query',
119
- short: '-q QUERY',
120
- long: '--query QUERY',
127
+ option :id,
128
+ description: 'ID of the ElasticSearch document to check for existence',
129
+ long: '--id ID',
121
130
  required: true
122
131
 
123
132
  option :host,
@@ -136,8 +145,7 @@ class ESQueryExists < Sensu::Plugin::Check::CLI
136
145
  option :scheme,
137
146
  description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
138
147
  short: '-s SCHEME',
139
- long: '--scheme SCHEME',
140
- default: 'https'
148
+ long: '--scheme SCHEME'
141
149
 
142
150
  option :password,
143
151
  description: 'Elasticsearch connection password',
@@ -157,28 +165,35 @@ class ESQueryExists < Sensu::Plugin::Check::CLI
157
165
  default: 30
158
166
 
159
167
  option :warn,
160
- short: '-w N',
161
- long: '--warn N',
162
- description: 'Result count WARNING threshold',
163
- proc: proc(&:to_i),
164
- default: 0
165
-
166
- option :crit,
167
- short: '-c N',
168
- long: '--crit N',
169
- description: 'Result count CRITICAL threshold',
170
- proc: proc(&:to_i),
171
- default: 0
168
+ short: '-w',
169
+ long: '--warn',
170
+ description: 'Warn instead of critical',
171
+ boolean: true,
172
+ default: false
172
173
 
173
174
  option :invert,
174
175
  long: '--invert',
175
- description: 'Invert thresholds',
176
- boolean: true
176
+ description: 'Invert status',
177
+ boolean: true,
178
+ default: false
177
179
 
178
- def run # rubocop:disable all
179
- client.exists(build_request_options)
180
+ def run
181
+ if client.exists?(build_request_options)
182
+ if config[:invert]
183
+ if config[:warn]
184
+ warning
185
+ else
186
+ critical
187
+ end
188
+ else
189
+ ok
190
+ end
191
+ elsif config[:invert]
180
192
  ok
181
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
193
+ elsif config[:warn]
194
+ warning
195
+ else
182
196
  critical
183
197
  end
198
+ end
184
199
  end
@@ -0,0 +1,99 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # handler-es-delete-indices.rb
4
+ #
5
+ # DESCRIPTION:
6
+ # This handler deletes indices.
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
+ # Deletes the indices given to it from a check output and a configured
21
+ # regex, and then deletes the indices matched.
22
+ #
23
+ # NOTES:
24
+ #
25
+ # LICENSE:
26
+ # Brendan Leon Gibat <brendan.gibat@gmail.com>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ require 'sensu-handler'
32
+ require 'elasticsearch'
33
+ require 'aws_es_transport'
34
+ require 'sensu-plugins-elasticsearch'
35
+
36
+ class ESIndexCleanup < Sensu::Handler
37
+ include ElasticsearchCommon
38
+
39
+ option :transport,
40
+ long: '--transport TRANSPORT',
41
+ description: 'Transport to use to communicate with ES. Use "AWS" for signed AWS transports.'
42
+
43
+ option :region,
44
+ long: '--region REGION',
45
+ description: 'Region (necessary for AWS Transport)'
46
+
47
+ option :host,
48
+ description: 'Elasticsearch host',
49
+ short: '-h HOST',
50
+ long: '--host HOST',
51
+ default: 'localhost'
52
+
53
+ option :port,
54
+ description: 'Elasticsearch port',
55
+ short: '-p PORT',
56
+ long: '--port PORT',
57
+ proc: proc(&:to_i),
58
+ default: 9200
59
+
60
+ option :scheme,
61
+ description: 'Elasticsearch connection scheme, defaults to https for authenticated connections',
62
+ short: '-s SCHEME',
63
+ long: '--scheme SCHEME'
64
+
65
+ option :password,
66
+ description: 'Elasticsearch connection password',
67
+ short: '-P PASSWORD',
68
+ long: '--password PASSWORD'
69
+
70
+ option :user,
71
+ description: 'Elasticsearch connection user',
72
+ short: '-u USER',
73
+ long: '--user USER'
74
+
75
+ option :timeout,
76
+ description: 'Elasticsearch query timeout in seconds',
77
+ short: '-t TIMEOUT',
78
+ long: '--timeout TIMEOUT',
79
+ proc: proc(&:to_i),
80
+ default: 60
81
+
82
+ option :event_regex,
83
+ description: 'Elasticsearch connection user',
84
+ short: '-e EVENT_REGEX',
85
+ long: '--event-regex EVENT_REGEX',
86
+ default: 'INDEX\[([^\]]+)\]'
87
+
88
+ def handle
89
+ event_regex = Regexp.new(config[:event_regex])
90
+ indices_to_delete = @event['check']['output'].scan(event_regex).flatten
91
+ if !indices_to_delete.nil? && !indices_to_delete.empty?
92
+
93
+ puts("Deleting indices: [ #{indices_to_delete.sort.join(', ')} ]")
94
+ client.indices.delete index: indices_to_delete
95
+ else
96
+ puts('No indices matched pattern to delete.')
97
+ end
98
+ end
99
+ end
@@ -15,6 +15,7 @@
15
15
  # Released under the same terms as Sensu (the MIT license); see LICENSE
16
16
  # for details.
17
17
  #
18
+
18
19
  require_relative 'elasticsearch-query.rb'
19
20
 
20
21
  module ElasticsearchCommon
@@ -24,19 +25,24 @@ module ElasticsearchCommon
24
25
  end
25
26
 
26
27
  def client
27
- @client ||= begin
28
- if !config[:user].nil? && !config[:pass].nil? && !config[:scheme].nil?
29
- Elasticsearch::Client.new hosts: [{
30
- host: config[:host],
31
- port: config[:port],
32
- user: config[:user],
33
- password: config[:password],
34
- scheme: config[:scheme],
35
- request_timeout: config[:timeout]
36
- }]
37
- else
38
- Elasticsearch::Client.new host: "#{config[:host]}:#{config[:port]}", request_timeout: config[:timeout]
39
- end
28
+ transport_class = nil
29
+ if config[:transport] == 'AWS'
30
+ transport_class = Elasticsearch::Transport::Transport::HTTP::AWS
40
31
  end
32
+
33
+ host = {
34
+ host: config[:host],
35
+ port: config[:port],
36
+ request_timeout: config[:timeout],
37
+ scheme: config[:scheme]
38
+ }
39
+
40
+ if !config[:user].nil? && !config[:password].nil?
41
+ host[:user] = config[:user]
42
+ host[:password] = config[:password]
43
+ host[:scheme] = 'https' unless config[:scheme]
44
+ end
45
+
46
+ @client ||= Elasticsearch::Client.new(transport_class: transport_class, hosts: [host], region: config[:region])
41
47
  end
42
48
  end
@@ -63,10 +63,19 @@ module ElasticsearchQuery
63
63
  def build_request_options
64
64
  end_time = (Time.now.utc - config[:offset])
65
65
  options = {
66
+
66
67
  index: indices(end_time),
67
68
  ignore_unavailable: true
68
69
  }
69
70
 
71
+ unless config[:ignore_unavailable].nil?
72
+ options[:ignore_unavailable] = config[:ignore_unavailable]
73
+ end
74
+
75
+ unless config[:id].nil?
76
+ options[:id] = config[:id]
77
+ end
78
+
70
79
  if !config[:body].nil?
71
80
  options[:body] = config[:body]
72
81
  else
@@ -1,8 +1,8 @@
1
1
  module SensuPluginsElasticsearch
2
2
  module Version
3
- MAJOR = 0
4
- MINOR = 5
5
- PATCH = 3
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
6
 
7
7
  VER_STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  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: 0.5.3
4
+ version: 1.0.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: 2016-04-02 00:00:00.000000000 Z
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -28,170 +28,202 @@ dependencies:
28
28
  name: elasticsearch
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.0.14
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.14
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-es-transport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: sensu-plugin
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ~>
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
61
  version: '1.2'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ~>
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.8'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.8'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: bundler
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
- - - ~>
87
+ - - "~>"
60
88
  - !ruby/object:Gem::Version
61
89
  version: '1.7'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
- - - ~>
94
+ - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '1.7'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: codeclimate-test-reporter
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
- - - ~>
101
+ - - "~>"
74
102
  - !ruby/object:Gem::Version
75
103
  version: '0.4'
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
- - - ~>
108
+ - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '0.4'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: github-markup
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - ~>
115
+ - - "~>"
88
116
  - !ruby/object:Gem::Version
89
117
  version: '1.3'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - ~>
122
+ - - "~>"
95
123
  - !ruby/object:Gem::Version
96
124
  version: '1.3'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: pry
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
- - - ~>
129
+ - - "~>"
102
130
  - !ruby/object:Gem::Version
103
131
  version: '0.10'
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - ~>
136
+ - - "~>"
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0.10'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: rake
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
- - - ~>
143
+ - - "~>"
116
144
  - !ruby/object:Gem::Version
117
145
  version: '10.0'
118
146
  type: :development
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
- - - ~>
150
+ - - "~>"
123
151
  - !ruby/object:Gem::Version
124
152
  version: '10.0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: redcarpet
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
- - - ~>
157
+ - - "~>"
130
158
  - !ruby/object:Gem::Version
131
159
  version: '3.2'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
- - - ~>
164
+ - - "~>"
137
165
  - !ruby/object:Gem::Version
138
166
  version: '3.2'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: rubocop
141
169
  requirement: !ruby/object:Gem::Requirement
142
170
  requirements:
143
- - - ~>
171
+ - - "~>"
144
172
  - !ruby/object:Gem::Version
145
- version: '0.37'
173
+ version: 0.40.0
146
174
  type: :development
147
175
  prerelease: false
148
176
  version_requirements: !ruby/object:Gem::Requirement
149
177
  requirements:
150
- - - ~>
178
+ - - "~>"
151
179
  - !ruby/object:Gem::Version
152
- version: '0.37'
180
+ version: 0.40.0
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: rspec
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
- - - ~>
185
+ - - "~>"
158
186
  - !ruby/object:Gem::Version
159
187
  version: '3.1'
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
- - - ~>
192
+ - - "~>"
165
193
  - !ruby/object:Gem::Version
166
194
  version: '3.1'
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: yard
169
197
  requirement: !ruby/object:Gem::Requirement
170
198
  requirements:
171
- - - ~>
199
+ - - "~>"
172
200
  - !ruby/object:Gem::Version
173
201
  version: '0.8'
174
202
  type: :development
175
203
  prerelease: false
176
204
  version_requirements: !ruby/object:Gem::Requirement
177
205
  requirements:
178
- - - ~>
206
+ - - "~>"
179
207
  - !ruby/object:Gem::Version
180
208
  version: '0.8'
181
- description: ! "This plugin provides native ElasticSearch instrumentation\n for
182
- monitoring and metrics collection, including:\n service
183
- health and metrics for cluster, node, and more."
184
- email: <sensu-users@googlegroups.com>
209
+ description: |-
210
+ This plugin provides native ElasticSearch instrumentation
211
+ for monitoring and metrics collection, including:
212
+ service health and metrics for cluster, node, and more.
213
+ email: "<sensu-users@googlegroups.com>"
185
214
  executables:
186
215
  - check-es-circuit-breakers.rb
216
+ - check-es-cluster-health.rb
187
217
  - check-es-cluster-status.rb
188
218
  - check-es-file-descriptors.rb
189
219
  - check-es-heap.rb
190
220
  - check-es-indexes.rb
221
+ - check-es-indices-sizes.rb
191
222
  - check-es-node-status.rb
192
223
  - check-es-query-count.rb
193
224
  - check-es-query-exists.rb
194
225
  - check-es-shard-allocation-status.rb
226
+ - handler-es-delete-indices.rb
195
227
  - metrics-es-cluster.rb
196
228
  - metrics-es-node-graphite.rb
197
229
  - metrics-es-node.rb
@@ -202,14 +234,17 @@ files:
202
234
  - LICENSE
203
235
  - README.md
204
236
  - bin/check-es-circuit-breakers.rb
237
+ - bin/check-es-cluster-health.rb
205
238
  - bin/check-es-cluster-status.rb
206
239
  - bin/check-es-file-descriptors.rb
207
240
  - bin/check-es-heap.rb
208
241
  - bin/check-es-indexes.rb
242
+ - bin/check-es-indices-sizes.rb
209
243
  - bin/check-es-node-status.rb
210
244
  - bin/check-es-query-count.rb
211
245
  - bin/check-es-query-exists.rb
212
246
  - bin/check-es-shard-allocation-status.rb
247
+ - bin/handler-es-delete-indices.rb
213
248
  - bin/metrics-es-cluster.rb
214
249
  - bin/metrics-es-node-graphite.rb
215
250
  - bin/metrics-es-node.rb
@@ -233,17 +268,17 @@ require_paths:
233
268
  - lib
234
269
  required_ruby_version: !ruby/object:Gem::Requirement
235
270
  requirements:
236
- - - ! '>='
271
+ - - ">="
237
272
  - !ruby/object:Gem::Version
238
- version: 1.9.3
273
+ version: 2.0.0
239
274
  required_rubygems_version: !ruby/object:Gem::Requirement
240
275
  requirements:
241
- - - ! '>='
276
+ - - ">="
242
277
  - !ruby/object:Gem::Version
243
278
  version: '0'
244
279
  requirements: []
245
280
  rubyforge_project:
246
- rubygems_version: 2.4.5
281
+ rubygems_version: 2.5.1
247
282
  signing_key:
248
283
  specification_version: 4
249
284
  summary: Sensu plugins for elasticsearch