fluent-plugin-elasticsearch 3.5.3 → 3.5.4
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/.coveralls.yml +2 -2
- data/.editorconfig +9 -9
- data/.gitignore +18 -18
- data/.travis.yml +18 -18
- data/Gemfile +9 -9
- data/History.md +390 -384
- data/ISSUE_TEMPLATE.md +27 -27
- data/LICENSE.txt +201 -201
- data/PULL_REQUEST_TEMPLATE.md +10 -10
- data/README.md +1515 -1398
- data/Rakefile +11 -11
- data/appveyor.yml +30 -30
- data/fluent-plugin-elasticsearch.gemspec +31 -31
- data/lib/fluent/log-ext.rb +38 -38
- data/lib/fluent/plugin/elasticsearch_constants.rb +13 -13
- data/lib/fluent/plugin/elasticsearch_error.rb +5 -5
- data/lib/fluent/plugin/elasticsearch_error_handler.rb +122 -122
- data/lib/fluent/plugin/elasticsearch_index_template.rb +112 -110
- data/lib/fluent/plugin/elasticsearch_simple_sniffer.rb +10 -10
- data/lib/fluent/plugin/filter_elasticsearch_genid.rb +25 -25
- data/lib/fluent/plugin/oj_serializer.rb +22 -22
- data/lib/fluent/plugin/out_elasticsearch.rb +777 -776
- data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +262 -262
- data/test/helper.rb +24 -24
- data/test/plugin/test_alias_template.json +8 -8
- data/test/plugin/test_elasticsearch_error_handler.rb +503 -503
- data/test/plugin/test_filter_elasticsearch_genid.rb +44 -44
- data/test/plugin/test_out_elasticsearch.rb +2720 -2720
- data/test/plugin/test_out_elasticsearch_dynamic.rb +1001 -1001
- data/test/plugin/test_template.json +23 -23
- data/test/test_log-ext.rb +35 -35
- metadata +4 -3
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rake/testtask'
|
3
|
-
|
4
|
-
Rake::TestTask.new(:test) do |test|
|
5
|
-
test.libs << 'test'
|
6
|
-
test.pattern = 'test/**/test_*.rb'
|
7
|
-
test.verbose = true
|
8
|
-
test.warning = false
|
9
|
-
end
|
10
|
-
|
11
|
-
task :default => :test
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |test|
|
5
|
+
test.libs << 'test'
|
6
|
+
test.pattern = 'test/**/test_*.rb'
|
7
|
+
test.verbose = true
|
8
|
+
test.warning = false
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :test
|
data/appveyor.yml
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
version: '{build}'
|
2
|
-
install:
|
3
|
-
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
4
|
-
- "%devkit%\\devkitvars.bat"
|
5
|
-
- IF EXIST "%devkit%\\bin\\ridk.cmd" ridk.cmd enable
|
6
|
-
- ruby --version
|
7
|
-
- gem --version
|
8
|
-
- bundle install
|
9
|
-
build: off
|
10
|
-
test_script:
|
11
|
-
- bundle exec rake test
|
12
|
-
|
13
|
-
# https://www.appveyor.com/docs/installed-software/#ruby
|
14
|
-
environment:
|
15
|
-
matrix:
|
16
|
-
- ruby_version: "25-x64"
|
17
|
-
devkit: C:\Ruby23-x64\DevKit
|
18
|
-
- ruby_version: "25"
|
19
|
-
devkit: C:\Ruby23\DevKit
|
20
|
-
- ruby_version: "24-x64"
|
21
|
-
devkit: C:\Ruby23-x64\DevKit
|
22
|
-
- ruby_version: "24"
|
23
|
-
devkit: C:\Ruby23\DevKit
|
24
|
-
- ruby_version: "23-x64"
|
25
|
-
devkit: C:\Ruby23-x64\DevKit
|
26
|
-
- ruby_version: "22-x64"
|
27
|
-
devkit: C:\Ruby23-x64\DevKit
|
28
|
-
matrix:
|
29
|
-
allow_failures:
|
30
|
-
- ruby_version: "21"
|
1
|
+
version: '{build}'
|
2
|
+
install:
|
3
|
+
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
4
|
+
- "%devkit%\\devkitvars.bat"
|
5
|
+
- IF EXIST "%devkit%\\bin\\ridk.cmd" ridk.cmd enable
|
6
|
+
- ruby --version
|
7
|
+
- gem --version
|
8
|
+
- bundle install
|
9
|
+
build: off
|
10
|
+
test_script:
|
11
|
+
- bundle exec rake test
|
12
|
+
|
13
|
+
# https://www.appveyor.com/docs/installed-software/#ruby
|
14
|
+
environment:
|
15
|
+
matrix:
|
16
|
+
- ruby_version: "25-x64"
|
17
|
+
devkit: C:\Ruby23-x64\DevKit
|
18
|
+
- ruby_version: "25"
|
19
|
+
devkit: C:\Ruby23\DevKit
|
20
|
+
- ruby_version: "24-x64"
|
21
|
+
devkit: C:\Ruby23-x64\DevKit
|
22
|
+
- ruby_version: "24"
|
23
|
+
devkit: C:\Ruby23\DevKit
|
24
|
+
- ruby_version: "23-x64"
|
25
|
+
devkit: C:\Ruby23-x64\DevKit
|
26
|
+
- ruby_version: "22-x64"
|
27
|
+
devkit: C:\Ruby23-x64\DevKit
|
28
|
+
matrix:
|
29
|
+
allow_failures:
|
30
|
+
- ruby_version: "21"
|
@@ -1,31 +1,31 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path('../lib', __FILE__)
|
3
|
-
|
4
|
-
Gem::Specification.new do |s|
|
5
|
-
s.name = 'fluent-plugin-elasticsearch'
|
6
|
-
s.version = '3.5.
|
7
|
-
s.authors = ['diogo', 'pitr']
|
8
|
-
s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com']
|
9
|
-
s.description = %q{Elasticsearch output plugin for Fluent event collector}
|
10
|
-
s.summary = s.description
|
11
|
-
s.homepage = 'https://github.com/uken/fluent-plugin-elasticsearch'
|
12
|
-
s.license = 'Apache-2.0'
|
13
|
-
|
14
|
-
s.files = `git ls-files`.split($/)
|
15
|
-
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
-
s.require_paths = ['lib']
|
18
|
-
|
19
|
-
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
20
|
-
|
21
|
-
s.add_runtime_dependency 'fluentd', '>= 0.14.22'
|
22
|
-
s.add_runtime_dependency 'excon', '>= 0'
|
23
|
-
s.add_runtime_dependency 'elasticsearch'
|
24
|
-
|
25
|
-
|
26
|
-
s.add_development_dependency 'rake', '>= 0'
|
27
|
-
s.add_development_dependency 'webmock', '~> 1'
|
28
|
-
s.add_development_dependency 'test-unit', '~> 3.1.0'
|
29
|
-
s.add_development_dependency 'minitest', '~> 5.8'
|
30
|
-
s.add_development_dependency 'flexmock', '~> 2.0'
|
31
|
-
end
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'fluent-plugin-elasticsearch'
|
6
|
+
s.version = '3.5.4'
|
7
|
+
s.authors = ['diogo', 'pitr']
|
8
|
+
s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com']
|
9
|
+
s.description = %q{Elasticsearch output plugin for Fluent event collector}
|
10
|
+
s.summary = s.description
|
11
|
+
s.homepage = 'https://github.com/uken/fluent-plugin-elasticsearch'
|
12
|
+
s.license = 'Apache-2.0'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split($/)
|
15
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'fluentd', '>= 0.14.22'
|
22
|
+
s.add_runtime_dependency 'excon', '>= 0'
|
23
|
+
s.add_runtime_dependency 'elasticsearch'
|
24
|
+
|
25
|
+
|
26
|
+
s.add_development_dependency 'rake', '>= 0'
|
27
|
+
s.add_development_dependency 'webmock', '~> 1'
|
28
|
+
s.add_development_dependency 'test-unit', '~> 3.1.0'
|
29
|
+
s.add_development_dependency 'minitest', '~> 5.8'
|
30
|
+
s.add_development_dependency 'flexmock', '~> 2.0'
|
31
|
+
end
|
data/lib/fluent/log-ext.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
|
-
require 'fluent/log'
|
2
|
-
# For elasticsearch-ruby v7.0.0 or later
|
3
|
-
# logger for Elasticsearch::Loggable required the following methods:
|
4
|
-
#
|
5
|
-
# * debug?
|
6
|
-
# * info?
|
7
|
-
# * warn?
|
8
|
-
# * error?
|
9
|
-
# * fatal?
|
10
|
-
|
11
|
-
module Fluent
|
12
|
-
class Log
|
13
|
-
# Elasticsearch::Loggable does not request trace? method.
|
14
|
-
# def trace?
|
15
|
-
# @level <= LEVEL_TRACE
|
16
|
-
# end
|
17
|
-
|
18
|
-
def debug?
|
19
|
-
@level <= LEVEL_DEBUG
|
20
|
-
end
|
21
|
-
|
22
|
-
def info?
|
23
|
-
@level <= LEVEL_INFO
|
24
|
-
end
|
25
|
-
|
26
|
-
def warn?
|
27
|
-
@level <= LEVEL_WARN
|
28
|
-
end
|
29
|
-
|
30
|
-
def error?
|
31
|
-
@level <= LEVEL_ERROR
|
32
|
-
end
|
33
|
-
|
34
|
-
def fatal?
|
35
|
-
@level <= LEVEL_FATAL
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
require 'fluent/log'
|
2
|
+
# For elasticsearch-ruby v7.0.0 or later
|
3
|
+
# logger for Elasticsearch::Loggable required the following methods:
|
4
|
+
#
|
5
|
+
# * debug?
|
6
|
+
# * info?
|
7
|
+
# * warn?
|
8
|
+
# * error?
|
9
|
+
# * fatal?
|
10
|
+
|
11
|
+
module Fluent
|
12
|
+
class Log
|
13
|
+
# Elasticsearch::Loggable does not request trace? method.
|
14
|
+
# def trace?
|
15
|
+
# @level <= LEVEL_TRACE
|
16
|
+
# end
|
17
|
+
|
18
|
+
def debug?
|
19
|
+
@level <= LEVEL_DEBUG
|
20
|
+
end
|
21
|
+
|
22
|
+
def info?
|
23
|
+
@level <= LEVEL_INFO
|
24
|
+
end
|
25
|
+
|
26
|
+
def warn?
|
27
|
+
@level <= LEVEL_WARN
|
28
|
+
end
|
29
|
+
|
30
|
+
def error?
|
31
|
+
@level <= LEVEL_ERROR
|
32
|
+
end
|
33
|
+
|
34
|
+
def fatal?
|
35
|
+
@level <= LEVEL_FATAL
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module Fluent
|
2
|
-
module Plugin
|
3
|
-
module ElasticsearchConstants
|
4
|
-
BODY_DELIMITER = "\n".freeze
|
5
|
-
UPDATE_OP = "update".freeze
|
6
|
-
UPSERT_OP = "upsert".freeze
|
7
|
-
CREATE_OP = "create".freeze
|
8
|
-
INDEX_OP = "index".freeze
|
9
|
-
ID_FIELD = "_id".freeze
|
10
|
-
TIMESTAMP_FIELD = "@timestamp".freeze
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
1
|
+
module Fluent
|
2
|
+
module Plugin
|
3
|
+
module ElasticsearchConstants
|
4
|
+
BODY_DELIMITER = "\n".freeze
|
5
|
+
UPDATE_OP = "update".freeze
|
6
|
+
UPSERT_OP = "upsert".freeze
|
7
|
+
CREATE_OP = "create".freeze
|
8
|
+
INDEX_OP = "index".freeze
|
9
|
+
ID_FIELD = "_id".freeze
|
10
|
+
TIMESTAMP_FIELD = "@timestamp".freeze
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'fluent/error'
|
2
|
-
|
3
|
-
class Fluent::Plugin::ElasticsearchError
|
4
|
-
class RetryableOperationExhaustedFailure < Fluent::UnrecoverableError; end
|
5
|
-
end
|
1
|
+
require 'fluent/error'
|
2
|
+
|
3
|
+
class Fluent::Plugin::ElasticsearchError
|
4
|
+
class RetryableOperationExhaustedFailure < Fluent::UnrecoverableError; end
|
5
|
+
end
|
@@ -1,122 +1,122 @@
|
|
1
|
-
require 'fluent/event'
|
2
|
-
require 'fluent/error'
|
3
|
-
require_relative 'elasticsearch_constants'
|
4
|
-
|
5
|
-
class Fluent::Plugin::ElasticsearchErrorHandler
|
6
|
-
include Fluent::Plugin::ElasticsearchConstants
|
7
|
-
|
8
|
-
attr_accessor :bulk_message_count
|
9
|
-
class ElasticsearchVersionMismatch < Fluent::UnrecoverableError; end
|
10
|
-
class ElasticsearchSubmitMismatch < Fluent::UnrecoverableError; end
|
11
|
-
class ElasticsearchRequestAbortError < Fluent::UnrecoverableError; end
|
12
|
-
class ElasticsearchError < StandardError; end
|
13
|
-
|
14
|
-
def initialize(plugin)
|
15
|
-
@plugin = plugin
|
16
|
-
end
|
17
|
-
|
18
|
-
def unrecoverable_error_types
|
19
|
-
@plugin.unrecoverable_error_types
|
20
|
-
end
|
21
|
-
|
22
|
-
def unrecoverable_error?(type)
|
23
|
-
unrecoverable_error_types.include?(type)
|
24
|
-
end
|
25
|
-
|
26
|
-
def log_es_400_reason(&block)
|
27
|
-
if @plugin.log_es_400_reason
|
28
|
-
block.call
|
29
|
-
else
|
30
|
-
@plugin.log.on_debug &block
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def handle_error(response, tag, chunk, bulk_message_count, extracted_values)
|
35
|
-
items = response['items']
|
36
|
-
if items.nil? || !items.is_a?(Array)
|
37
|
-
raise ElasticsearchVersionMismatch, "The response format was unrecognized: #{response}"
|
38
|
-
end
|
39
|
-
if bulk_message_count != items.length
|
40
|
-
raise ElasticsearchSubmitMismatch, "The number of records submitted #{bulk_message_count} do not match the number returned #{items.length}. Unable to process bulk response."
|
41
|
-
end
|
42
|
-
retry_stream = Fluent::MultiEventStream.new
|
43
|
-
stats = Hash.new(0)
|
44
|
-
meta = {}
|
45
|
-
header = {}
|
46
|
-
chunk.msgpack_each do |time, rawrecord|
|
47
|
-
bulk_message = ''
|
48
|
-
next unless rawrecord.is_a? Hash
|
49
|
-
begin
|
50
|
-
# we need a deep copy for process_message to alter
|
51
|
-
processrecord = Marshal.load(Marshal.dump(rawrecord))
|
52
|
-
meta, header, record = @plugin.process_message(tag, meta, header, time, processrecord, extracted_values)
|
53
|
-
next unless @plugin.append_record_to_messages(@plugin.write_operation, meta, header, record, bulk_message)
|
54
|
-
rescue => e
|
55
|
-
stats[:bad_chunk_record] += 1
|
56
|
-
next
|
57
|
-
end
|
58
|
-
item = items.shift
|
59
|
-
if item.is_a?(Hash) && item.has_key?(@plugin.write_operation)
|
60
|
-
write_operation = @plugin.write_operation
|
61
|
-
elsif INDEX_OP == @plugin.write_operation && item.is_a?(Hash) && item.has_key?(CREATE_OP)
|
62
|
-
write_operation = CREATE_OP
|
63
|
-
elsif item.nil?
|
64
|
-
stats[:errors_nil_resp] += 1
|
65
|
-
next
|
66
|
-
else
|
67
|
-
# When we don't have an expected ops field, something changed in the API
|
68
|
-
# expected return values (ES 2.x)
|
69
|
-
stats[:errors_bad_resp] += 1
|
70
|
-
next
|
71
|
-
end
|
72
|
-
if item[write_operation].has_key?('status')
|
73
|
-
status = item[write_operation]['status']
|
74
|
-
else
|
75
|
-
# When we don't have a status field, something changed in the API
|
76
|
-
# expected return values (ES 2.x)
|
77
|
-
stats[:errors_bad_resp] += 1
|
78
|
-
next
|
79
|
-
end
|
80
|
-
case
|
81
|
-
when [200, 201].include?(status)
|
82
|
-
stats[:successes] += 1
|
83
|
-
when CREATE_OP == write_operation && 409 == status
|
84
|
-
stats[:duplicates] += 1
|
85
|
-
when 400 == status
|
86
|
-
stats[:bad_argument] += 1
|
87
|
-
reason = ""
|
88
|
-
log_es_400_reason do
|
89
|
-
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
|
90
|
-
reason = " [error type]: #{item[write_operation]['error']['type']}"
|
91
|
-
end
|
92
|
-
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('reason')
|
93
|
-
reason += " [reason]: \'#{item[write_operation]['error']['reason']}\'"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
@plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("400 - Rejected by Elasticsearch#{reason}"))
|
97
|
-
else
|
98
|
-
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
|
99
|
-
type = item[write_operation]['error']['type']
|
100
|
-
stats[type] += 1
|
101
|
-
retry_stream.add(time, rawrecord)
|
102
|
-
if unrecoverable_error?(type)
|
103
|
-
raise ElasticsearchRequestAbortError, "Rejected Elasticsearch due to #{type}"
|
104
|
-
end
|
105
|
-
else
|
106
|
-
# When we don't have a type field, something changed in the API
|
107
|
-
# expected return values (ES 2.x)
|
108
|
-
stats[:errors_bad_resp] += 1
|
109
|
-
@plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("#{status} - No error type provided in the response"))
|
110
|
-
next
|
111
|
-
end
|
112
|
-
stats[type] += 1
|
113
|
-
end
|
114
|
-
end
|
115
|
-
@plugin.log.on_debug do
|
116
|
-
msg = ["Indexed (op = #{@plugin.write_operation})"]
|
117
|
-
stats.each_pair { |key, value| msg << "#{value} #{key}" }
|
118
|
-
@plugin.log.debug msg.join(', ')
|
119
|
-
end
|
120
|
-
raise Fluent::Plugin::ElasticsearchOutput::RetryStreamError.new(retry_stream) unless retry_stream.empty?
|
121
|
-
end
|
122
|
-
end
|
1
|
+
require 'fluent/event'
|
2
|
+
require 'fluent/error'
|
3
|
+
require_relative 'elasticsearch_constants'
|
4
|
+
|
5
|
+
class Fluent::Plugin::ElasticsearchErrorHandler
|
6
|
+
include Fluent::Plugin::ElasticsearchConstants
|
7
|
+
|
8
|
+
attr_accessor :bulk_message_count
|
9
|
+
class ElasticsearchVersionMismatch < Fluent::UnrecoverableError; end
|
10
|
+
class ElasticsearchSubmitMismatch < Fluent::UnrecoverableError; end
|
11
|
+
class ElasticsearchRequestAbortError < Fluent::UnrecoverableError; end
|
12
|
+
class ElasticsearchError < StandardError; end
|
13
|
+
|
14
|
+
def initialize(plugin)
|
15
|
+
@plugin = plugin
|
16
|
+
end
|
17
|
+
|
18
|
+
def unrecoverable_error_types
|
19
|
+
@plugin.unrecoverable_error_types
|
20
|
+
end
|
21
|
+
|
22
|
+
def unrecoverable_error?(type)
|
23
|
+
unrecoverable_error_types.include?(type)
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_es_400_reason(&block)
|
27
|
+
if @plugin.log_es_400_reason
|
28
|
+
block.call
|
29
|
+
else
|
30
|
+
@plugin.log.on_debug &block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_error(response, tag, chunk, bulk_message_count, extracted_values)
|
35
|
+
items = response['items']
|
36
|
+
if items.nil? || !items.is_a?(Array)
|
37
|
+
raise ElasticsearchVersionMismatch, "The response format was unrecognized: #{response}"
|
38
|
+
end
|
39
|
+
if bulk_message_count != items.length
|
40
|
+
raise ElasticsearchSubmitMismatch, "The number of records submitted #{bulk_message_count} do not match the number returned #{items.length}. Unable to process bulk response."
|
41
|
+
end
|
42
|
+
retry_stream = Fluent::MultiEventStream.new
|
43
|
+
stats = Hash.new(0)
|
44
|
+
meta = {}
|
45
|
+
header = {}
|
46
|
+
chunk.msgpack_each do |time, rawrecord|
|
47
|
+
bulk_message = ''
|
48
|
+
next unless rawrecord.is_a? Hash
|
49
|
+
begin
|
50
|
+
# we need a deep copy for process_message to alter
|
51
|
+
processrecord = Marshal.load(Marshal.dump(rawrecord))
|
52
|
+
meta, header, record = @plugin.process_message(tag, meta, header, time, processrecord, extracted_values)
|
53
|
+
next unless @plugin.append_record_to_messages(@plugin.write_operation, meta, header, record, bulk_message)
|
54
|
+
rescue => e
|
55
|
+
stats[:bad_chunk_record] += 1
|
56
|
+
next
|
57
|
+
end
|
58
|
+
item = items.shift
|
59
|
+
if item.is_a?(Hash) && item.has_key?(@plugin.write_operation)
|
60
|
+
write_operation = @plugin.write_operation
|
61
|
+
elsif INDEX_OP == @plugin.write_operation && item.is_a?(Hash) && item.has_key?(CREATE_OP)
|
62
|
+
write_operation = CREATE_OP
|
63
|
+
elsif item.nil?
|
64
|
+
stats[:errors_nil_resp] += 1
|
65
|
+
next
|
66
|
+
else
|
67
|
+
# When we don't have an expected ops field, something changed in the API
|
68
|
+
# expected return values (ES 2.x)
|
69
|
+
stats[:errors_bad_resp] += 1
|
70
|
+
next
|
71
|
+
end
|
72
|
+
if item[write_operation].has_key?('status')
|
73
|
+
status = item[write_operation]['status']
|
74
|
+
else
|
75
|
+
# When we don't have a status field, something changed in the API
|
76
|
+
# expected return values (ES 2.x)
|
77
|
+
stats[:errors_bad_resp] += 1
|
78
|
+
next
|
79
|
+
end
|
80
|
+
case
|
81
|
+
when [200, 201].include?(status)
|
82
|
+
stats[:successes] += 1
|
83
|
+
when CREATE_OP == write_operation && 409 == status
|
84
|
+
stats[:duplicates] += 1
|
85
|
+
when 400 == status
|
86
|
+
stats[:bad_argument] += 1
|
87
|
+
reason = ""
|
88
|
+
log_es_400_reason do
|
89
|
+
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
|
90
|
+
reason = " [error type]: #{item[write_operation]['error']['type']}"
|
91
|
+
end
|
92
|
+
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('reason')
|
93
|
+
reason += " [reason]: \'#{item[write_operation]['error']['reason']}\'"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
@plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("400 - Rejected by Elasticsearch#{reason}"))
|
97
|
+
else
|
98
|
+
if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
|
99
|
+
type = item[write_operation]['error']['type']
|
100
|
+
stats[type] += 1
|
101
|
+
retry_stream.add(time, rawrecord)
|
102
|
+
if unrecoverable_error?(type)
|
103
|
+
raise ElasticsearchRequestAbortError, "Rejected Elasticsearch due to #{type}"
|
104
|
+
end
|
105
|
+
else
|
106
|
+
# When we don't have a type field, something changed in the API
|
107
|
+
# expected return values (ES 2.x)
|
108
|
+
stats[:errors_bad_resp] += 1
|
109
|
+
@plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("#{status} - No error type provided in the response"))
|
110
|
+
next
|
111
|
+
end
|
112
|
+
stats[type] += 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
@plugin.log.on_debug do
|
116
|
+
msg = ["Indexed (op = #{@plugin.write_operation})"]
|
117
|
+
stats.each_pair { |key, value| msg << "#{value} #{key}" }
|
118
|
+
@plugin.log.debug msg.join(', ')
|
119
|
+
end
|
120
|
+
raise Fluent::Plugin::ElasticsearchOutput::RetryStreamError.new(retry_stream) unless retry_stream.empty?
|
121
|
+
end
|
122
|
+
end
|