fluent-plugin-elasticsearch 1.15.1 → 1.15.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00a9fd19dd2727f3b8923ba7ecab25944afdcc52bc1e5b3f12571f95626640d8
4
- data.tar.gz: ff12458ed88da30d28a1256105c4c2b90e02706b30b691c63f6d257dcc12977c
3
+ metadata.gz: dc1ee6d297a64d46320b2b48b8528faf9a377f1a9af9274c083f36e0d7f48c88
4
+ data.tar.gz: ff6de82c88a71a3f8a3c47951fadf0b555fe4118feb18fe911c4ef7b66178218
5
5
  SHA512:
6
- metadata.gz: d6f158b0d213b1bea7efc8f7ca2c85cc07ffe92195692d2c8fe3b6a9ede345e02870033213894ccd1da8afc38df08535c92d7ef336ae0ef4ef1319e4ea9eef8b
7
- data.tar.gz: 3f8b3b2537b3d72017f9ca85493c97997fd4770937f8bd158836b9de7e48a7053a03abf42264fae0a64d56a5600f3f24c9a1edd4d918cf0d71b71377d5895d76
6
+ metadata.gz: 3123a75aeee15020ec775457d36bfe6eaf52ba22309163c37859ca096556605dc400a98495f587f954e2e7b4d4ad2aa9cf9b7010c9c75158d911feaa6e181fa9
7
+ data.tar.gz: 506fc86e5930c18c38992d477d7865363bd351851e141879c67834dca05828f710795fc63725a6f5bc7fde9732660fa97a5caec45d6361b6c974e391fa1ef36c
data/History.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
+ ### 1.15.2
6
+ - handle case where stats not processed in order; add testing (#410)
7
+
5
8
  ### 1.15.1
6
9
  - successful operation if all duplicates (#406)
7
10
 
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'fluent-plugin-elasticsearch'
6
- s.version = '1.15.1'
6
+ s.version = '1.15.2'
7
7
  s.authors = ['diogo', 'pitr']
8
8
  s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com']
9
9
  s.description = %q{Elasticsearch output plugin for Fluent event collector}
@@ -53,29 +53,24 @@ class Fluent::ElasticsearchErrorHandler
53
53
  stats[type] += 1
54
54
  end
55
55
  end
56
- if stats[:errors_bad_resp] > 0
57
- @plugin.log.on_debug { @plugin.log.debug("Unable to parse response from elasticsearch, likely an API version mismatch: #{response}") }
58
- raise ElasticsearchVersionMismatch, "Unable to parse error response from Elasticsearch, likely an API version mismatch. Add '@log_level debug' to your config to see the full response"
59
- end
60
56
  @plugin.log.on_debug do
61
57
  msg = ["Indexed (op = #{@plugin.write_operation})"]
62
58
  stats.each_pair { |key, value| msg << "#{value} #{key}" }
63
59
  @plugin.log.debug msg.join(', ')
64
60
  end
65
- if stats[:successes] + stats[:duplicates] == bulk_message_count
66
- @plugin.log.debug("retry succeeded - all #{bulk_message_count} records were successfully sent")
67
- return
68
- end
69
- stats.each_key do |key|
70
- case key
71
- when 'out_of_memory_error'
72
- raise ElasticsearchOutOfMemory, 'Elasticsearch has exhausted its heap, retrying'
73
- when 'es_rejected_execution_exception'
74
- raise BulkIndexQueueFull, 'Bulk index queue is full, retrying'
75
- else
76
- @plugin.log.on_debug { @plugin.log.debug("Elasticsearch errors returned, retrying: #{response}") }
77
- raise ElasticsearchError, "Elasticsearch returned errors, retrying. Add '@log_level debug' to your config to see the full response"
78
- end
61
+ case
62
+ when stats[:errors_bad_resp] > 0
63
+ @plugin.log.on_debug { @plugin.log.debug("Unable to parse response from elasticsearch, likely an API version mismatch: #{response}") }
64
+ raise ElasticsearchVersionMismatch, "Unable to parse error response from Elasticsearch, likely an API version mismatch. Add '@log_level debug' to your config to see the full response"
65
+ when stats[:successes] + stats[:duplicates] == bulk_message_count
66
+ @plugin.log.info("retry succeeded - successes=#{stats[:successes]} duplicates=#{stats[:duplicates]}")
67
+ when stats['es_rejected_execution_exception'] > 0
68
+ raise BulkIndexQueueFull, 'Bulk index queue is full, retrying'
69
+ when stats['out_of_memory_error'] > 0
70
+ raise ElasticsearchOutOfMemory, 'Elasticsearch has exhausted its heap, retrying'
71
+ else
72
+ @plugin.log.on_debug { @plugin.log.debug("Elasticsearch errors returned, retrying: #{response}") }
73
+ raise ElasticsearchError, "Elasticsearch returned errors, retrying. Add '@log_level debug' to your config to see the full response"
79
74
  end
80
75
  end
81
76
  end
@@ -6,20 +6,25 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
6
6
 
7
7
  class TestPlugin
8
8
  attr_reader :log
9
+ attr_reader :write_operation
9
10
  def initialize(log)
10
11
  @log = log
11
- end
12
-
13
- def write_operation
14
- 'index'
12
+ @write_operation = 'index'
15
13
  end
16
14
  end
17
15
 
18
16
  def setup
19
17
  Fluent::Test.setup
20
- @log = Fluent::Engine.log
21
- plugin = TestPlugin.new(@log)
22
- @handler = Fluent::ElasticsearchErrorHandler.new(plugin)
18
+ @log_device = Fluent::Test::DummyLogDevice.new
19
+ if defined?(ServerEngine::DaemonLogger)
20
+ dl_opts = {:log_level => ServerEngine::DaemonLogger::INFO}
21
+ logger = ServerEngine::DaemonLogger.new(@log_device, dl_opts)
22
+ @log = Fluent::Log.new(logger)
23
+ else
24
+ @log = Fluent::Log.new(@log_device, Fluent::Log::LEVEL_INFO)
25
+ end
26
+ @plugin = TestPlugin.new(@log)
27
+ @handler = Fluent::ElasticsearchErrorHandler.new(@plugin)
23
28
  end
24
29
 
25
30
  def parse_response(value)
@@ -39,7 +44,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
39
44
  "status" : 500,
40
45
  "error" : {
41
46
  "type" : "some unrecognized type",
42
- "reason":"some error to cause version mismatch"
47
+ "reason":"unrecognized error"
43
48
  }
44
49
  }
45
50
  },
@@ -51,7 +56,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
51
56
  "status" : 500,
52
57
  "error" : {
53
58
  "type" : "some unrecognized type",
54
- "reason":"some error to cause version mismatch"
59
+ "reason":"unrecognized error"
55
60
  }
56
61
  }
57
62
  },
@@ -79,7 +84,7 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
79
84
  "status" : 400,
80
85
  "error" : {
81
86
  "type" : "some unrecognized type",
82
- "reason":"some error to cause version mismatch"
87
+ "reason":"unrecognized error"
83
88
  }
84
89
  }
85
90
  }
@@ -119,4 +124,171 @@ class TestElasticsearchErrorHandler < Test::Unit::TestCase
119
124
 
120
125
  end
121
126
 
127
+ def test_retry_with_successes_and_duplicates
128
+ response = parse_response(%(
129
+ {
130
+ "took" : 0,
131
+ "errors" : true,
132
+ "items" : [
133
+ {
134
+ "create" : {
135
+ "_index" : "foo",
136
+ "_type" : "bar",
137
+ "_id" : "abc",
138
+ "status" : 409,
139
+ "error" : {
140
+ "reason":"duplicate ID"
141
+ }
142
+ }
143
+ },
144
+ {
145
+ "create" : {
146
+ "_index" : "foo",
147
+ "_type" : "bar",
148
+ "_id" : "abc",
149
+ "status" : 201
150
+ }
151
+ }
152
+ ]
153
+ }
154
+ ))
155
+
156
+ @plugin.instance_variable_set(:@write_operation, 'create')
157
+ @handler.instance_variable_set(:@bulk_message_count, 2)
158
+ @handler.handle_error(response)
159
+ assert_match /retry succeeded - successes=1 duplicates=1/, @log.out.logs[0]
160
+ end
161
+
162
+ def test_bulk_rejection_errors
163
+ response = parse_response(%({
164
+ "took" : 0,
165
+ "errors" : true,
166
+ "items" : [
167
+ {
168
+ "create" : {
169
+ "_index" : "foo",
170
+ "_type" : "bar",
171
+ "_id" : "abc",
172
+ "status" : 500,
173
+ "error" : {
174
+ "type" : "some unrecognized type",
175
+ "reason":"unrecognized error"
176
+ }
177
+ }
178
+ },
179
+ {
180
+ "create" : {
181
+ "_index" : "foo",
182
+ "_type" : "bar",
183
+ "_id" : "abc",
184
+ "status" : 500,
185
+ "error" : {
186
+ "type" : "some unrecognized type",
187
+ "reason":"unrecognized error"
188
+ }
189
+ }
190
+ },
191
+ {
192
+ "create" : {
193
+ "_index" : "foo",
194
+ "_type" : "bar",
195
+ "_id" : "abc",
196
+ "status" : 201
197
+ }
198
+ },
199
+ {
200
+ "create" : {
201
+ "_index" : "foo",
202
+ "_type" : "bar",
203
+ "_id" : "abc",
204
+ "status" : 409
205
+ }
206
+ },
207
+ {
208
+ "create" : {
209
+ "_index" : "foo",
210
+ "_type" : "bar",
211
+ "_id" : "abc",
212
+ "status" : 429,
213
+ "error" : {
214
+ "type" : "es_rejected_execution_exception",
215
+ "reason":"Elasticsearch could not process bulk index request"
216
+ }
217
+ }
218
+ }
219
+ ]
220
+ }))
221
+
222
+ assert_raise Fluent::ElasticsearchErrorHandler::BulkIndexQueueFull do
223
+ @handler.handle_error(response)
224
+ end
225
+
226
+ end
227
+
228
+ def test_out_of_memory_errors
229
+ response = parse_response(%({
230
+ "took" : 0,
231
+ "errors" : true,
232
+ "items" : [
233
+ {
234
+ "create" : {
235
+ "_index" : "foo",
236
+ "_type" : "bar",
237
+ "_id" : "abc",
238
+ "status" : 500,
239
+ "error" : {
240
+ "type" : "some unrecognized type",
241
+ "reason":"unrecognized error"
242
+ }
243
+ }
244
+ },
245
+ {
246
+ "create" : {
247
+ "_index" : "foo",
248
+ "_type" : "bar",
249
+ "_id" : "abc",
250
+ "status" : 500,
251
+ "error" : {
252
+ "type" : "some unrecognized type",
253
+ "reason":"unrecognized error"
254
+ }
255
+ }
256
+ },
257
+ {
258
+ "create" : {
259
+ "_index" : "foo",
260
+ "_type" : "bar",
261
+ "_id" : "abc",
262
+ "status" : 201
263
+ }
264
+ },
265
+ {
266
+ "create" : {
267
+ "_index" : "foo",
268
+ "_type" : "bar",
269
+ "_id" : "abc",
270
+ "status" : 409
271
+ }
272
+ },
273
+ {
274
+ "create" : {
275
+ "_index" : "foo",
276
+ "_type" : "bar",
277
+ "_id" : "abc",
278
+ "status" : 400,
279
+ "error" : {
280
+ "type" : "out_of_memory_error",
281
+ "reason":"Elasticsearch exhausted its heap"
282
+ }
283
+ }
284
+ }
285
+ ]
286
+ }))
287
+
288
+ assert_raise Fluent::ElasticsearchErrorHandler::ElasticsearchOutOfMemory do
289
+ @handler.handle_error(response)
290
+ end
291
+
292
+ end
293
+
122
294
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - diogo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-22 00:00:00.000000000 Z
12
+ date: 2018-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd