logstash-output-elasticsearch 7.1.0-java → 7.2.0-java
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 +6 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json +45 -0
- data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +3 -3
- data/lib/logstash/outputs/elasticsearch/http_client.rb +5 -0
- data/lib/logstash/outputs/elasticsearch.rb +1 -1
- data/logstash-output-elasticsearch.gemspec +1 -1
- data/spec/fixtures/scripts/{scripted_update.groovy → groovy/scripted_update.groovy} +0 -0
- data/spec/fixtures/scripts/{scripted_update_nested.groovy → groovy/scripted_update_nested.groovy} +0 -0
- data/spec/fixtures/scripts/{scripted_upsert.groovy → groovy/scripted_upsert.groovy} +0 -0
- data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
- data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
- data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
- data/spec/integration/outputs/groovy_update_spec.rb +148 -0
- data/spec/integration/outputs/{pipeline_spec.rb → ingest_pipeline_spec.rb} +1 -0
- data/spec/integration/outputs/painless_update_spec.rb +148 -0
- data/spec/integration/outputs/parent_spec.rb +7 -3
- data/spec/integration/outputs/sniffer_spec.rb +1 -1
- data/spec/integration/outputs/update_spec.rb +2 -95
- data/spec/unit/outputs/elasticsearch/http_client_spec.rb +14 -0
- metadata +21 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bd235749fa8bfe679c896c6b5e82630b044e354
|
4
|
+
data.tar.gz: 376a1262982ce57c209ab671dd4532d78da68437
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f7528c39ce9314e4bcf62a2656e8a850e7000a376fc7aa0f97775841eb6d26c19df13f6aab027aaa9dadfa015a56753a5e7cf2327df58e95c65fa6e569e4e91
|
7
|
+
data.tar.gz: 7d56cc94de48b15c32ee97a7b55deb416d69d2f84c0824d7f3cf8c7da7845d542eabb99cd9d15ae44d8a048102d1471cc794b9daaa0cd5645dd1bb78770eab88
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 7.2.0
|
2
|
+
- Support 6.0.0-alpha1 version of Elasticsearch by adding a separate 6x template
|
3
|
+
- Note: This version is backwards compatible w.r.t. config, but for ES 6.0.0, `_all` has been
|
4
|
+
removed. This BWC issue only affects ES version 6.x; older versions
|
5
|
+
can be used with this plugin as is.
|
6
|
+
|
1
7
|
## 7.1.0
|
2
8
|
- Add support to compress requests using the new `http_compression` option.
|
3
9
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
{
|
2
|
+
"template" : "logstash-*",
|
3
|
+
"version" : 60001,
|
4
|
+
"settings" : {
|
5
|
+
"index.refresh_interval" : "5s"
|
6
|
+
},
|
7
|
+
"mappings" : {
|
8
|
+
"_default_" : {
|
9
|
+
"dynamic_templates" : [ {
|
10
|
+
"message_field" : {
|
11
|
+
"path_match" : "message",
|
12
|
+
"match_mapping_type" : "string",
|
13
|
+
"mapping" : {
|
14
|
+
"type" : "text",
|
15
|
+
"norms" : false
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}, {
|
19
|
+
"string_fields" : {
|
20
|
+
"match" : "*",
|
21
|
+
"match_mapping_type" : "string",
|
22
|
+
"mapping" : {
|
23
|
+
"type" : "text", "norms" : false,
|
24
|
+
"fields" : {
|
25
|
+
"keyword" : { "type": "keyword" }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
} ],
|
30
|
+
"properties" : {
|
31
|
+
"@timestamp": { "type": "date"},
|
32
|
+
"@version": { "type": "keyword"},
|
33
|
+
"geoip" : {
|
34
|
+
"dynamic": true,
|
35
|
+
"properties" : {
|
36
|
+
"ip": { "type": "ip" },
|
37
|
+
"location" : { "type" : "geo_point" },
|
38
|
+
"latitude" : { "type" : "half_float" },
|
39
|
+
"longitude" : { "type" : "half_float" }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
@@ -163,8 +163,8 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
|
|
163
163
|
return nil
|
164
164
|
else
|
165
165
|
case major_version(nodes)
|
166
|
-
when 5
|
167
|
-
|
166
|
+
when 5, 6
|
167
|
+
sniff_5x_and_above(nodes)
|
168
168
|
when 2
|
169
169
|
sniff_2x_1x(nodes)
|
170
170
|
when 1
|
@@ -180,7 +180,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
|
|
180
180
|
k,v = nodes.first; v['version'].split('.').first.to_i
|
181
181
|
end
|
182
182
|
|
183
|
-
def
|
183
|
+
def sniff_5x_and_above(nodes)
|
184
184
|
nodes.map do |id,info|
|
185
185
|
if info["http"]
|
186
186
|
uri = LogStash::Util::SafeURI.new(info["http"]["publish_address"])
|
@@ -143,6 +143,11 @@ module LogStash; module Outputs; class ElasticSearch;
|
|
143
143
|
LogStash::Json.load(response.body)
|
144
144
|
end
|
145
145
|
|
146
|
+
def get(path)
|
147
|
+
url, response = @pool.get(path, nil)
|
148
|
+
LogStash::Json.load(response.body)
|
149
|
+
end
|
150
|
+
|
146
151
|
def close
|
147
152
|
@pool.close
|
148
153
|
end
|
@@ -147,7 +147,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
147
147
|
# It can be either .jks or .p12
|
148
148
|
config :keystore, :validate => :path
|
149
149
|
|
150
|
-
# Set the
|
150
|
+
# Set the keystore password
|
151
151
|
config :keystore_password, :validate => :password
|
152
152
|
|
153
153
|
# This setting asks Elasticsearch for the list of all cluster nodes and adds them to the hosts list.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-elasticsearch'
|
3
|
-
s.version = '7.
|
3
|
+
s.version = '7.2.0'
|
4
4
|
s.licenses = ['apache-2.0']
|
5
5
|
s.summary = "Logstash Output to Elasticsearch"
|
6
6
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
File without changes
|
data/spec/fixtures/scripts/{scripted_update_nested.groovy → groovy/scripted_update_nested.groovy}
RENAMED
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
ctx._source.counter += params.event.data.count
|
@@ -0,0 +1 @@
|
|
1
|
+
ctx._source.counter = params.event.counter
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require_relative "../../../spec/es_spec_helper"
|
2
|
+
|
3
|
+
describe "Update actions using groovy scripts", :integration => true, :update_tests => 'groovy', :version_greater_than_equal_to_2x => true do
|
4
|
+
require "logstash/outputs/elasticsearch"
|
5
|
+
|
6
|
+
def get_es_output( options={} )
|
7
|
+
settings = {
|
8
|
+
"manage_template" => true,
|
9
|
+
"index" => "logstash-update",
|
10
|
+
"template_overwrite" => true,
|
11
|
+
"hosts" => get_host_port(),
|
12
|
+
"action" => "update",
|
13
|
+
"script_lang" => "groovy"
|
14
|
+
}
|
15
|
+
LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
|
16
|
+
end
|
17
|
+
|
18
|
+
before :each do
|
19
|
+
@es = get_client
|
20
|
+
# Delete all templates first.
|
21
|
+
# Clean ES of data before we start.
|
22
|
+
@es.indices.delete_template(:name => "*")
|
23
|
+
# This can fail if there are no indexes, ignore failure.
|
24
|
+
@es.indices.delete(:index => "*") rescue nil
|
25
|
+
@es.index(
|
26
|
+
:index => 'logstash-update',
|
27
|
+
:type => 'logs',
|
28
|
+
:id => "123",
|
29
|
+
:body => { :message => 'Test', :counter => 1 }
|
30
|
+
)
|
31
|
+
@es.indices.refresh
|
32
|
+
end
|
33
|
+
|
34
|
+
context "scripted updates" do
|
35
|
+
it "should increment a counter with event/doc 'count' variable" do
|
36
|
+
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update', 'script_type' => 'file' })
|
37
|
+
subject.register
|
38
|
+
subject.multi_receive([LogStash::Event.new("count" => 2)])
|
39
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
40
|
+
insist { r["_source"]["counter"] } == 3
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should increment a counter with event/doc '[data][count]' nested variable" do
|
44
|
+
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update_nested', 'script_type' => 'file' })
|
45
|
+
subject.register
|
46
|
+
subject.multi_receive([LogStash::Event.new("data" => { "count" => 3 })])
|
47
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
48
|
+
insist { r["_source"]["counter"] } == 4
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should increment a counter with event/doc 'count' variable with inline script" do
|
52
|
+
subject = get_es_output({
|
53
|
+
'document_id' => "123",
|
54
|
+
'script' => 'ctx._source.counter += event["counter"]',
|
55
|
+
'script_lang' => 'groovy',
|
56
|
+
'script_type' => 'inline'
|
57
|
+
})
|
58
|
+
subject.register
|
59
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
60
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
61
|
+
insist { r["_source"]["counter"] } == 4
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should increment a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
65
|
+
subject = get_es_output({
|
66
|
+
'document_id' => "123",
|
67
|
+
'doc_as_upsert' => true,
|
68
|
+
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["counter"]; } else { ctx._source.counter = event["counter"]; }',
|
69
|
+
'script_lang' => 'groovy',
|
70
|
+
'script_type' => 'inline'
|
71
|
+
})
|
72
|
+
subject.register
|
73
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
74
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
75
|
+
insist { r["_source"]["counter"] } == 4
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should, with new doc, set a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
79
|
+
subject = get_es_output({
|
80
|
+
'document_id' => "456",
|
81
|
+
'doc_as_upsert' => true,
|
82
|
+
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["count"]; } else { ctx._source.counter = event["count"]; }',
|
83
|
+
'script_lang' => 'groovy',
|
84
|
+
'script_type' => 'inline'
|
85
|
+
})
|
86
|
+
subject.register
|
87
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
88
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
89
|
+
insist { r["_source"]["counter"] } == 3
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should increment a counter with event/doc 'count' variable with indexed script" do
|
93
|
+
@es.put_script lang: 'groovy', id: 'indexed_update', body: { script: 'ctx._source.counter += event["count"]' }
|
94
|
+
subject = get_es_output({
|
95
|
+
'document_id' => "123",
|
96
|
+
'script' => 'indexed_update',
|
97
|
+
'script_lang' => 'groovy',
|
98
|
+
'script_type' => 'indexed'
|
99
|
+
})
|
100
|
+
subject.register
|
101
|
+
subject.multi_receive([LogStash::Event.new("count" => 4 )])
|
102
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
103
|
+
insist { r["_source"]["counter"] } == 5
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when update with upsert" do
|
108
|
+
it "should create new documents with provided upsert" do
|
109
|
+
subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
|
110
|
+
subject.register
|
111
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
112
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
113
|
+
insist { r["_source"]["message"] } == 'upsert message'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should create new documents with event/doc as upsert" do
|
117
|
+
subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true })
|
118
|
+
subject.register
|
119
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
120
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
121
|
+
insist { r["_source"]["message"] } == 'sample message here'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should fail on documents with event/doc as upsert at external version" do
|
125
|
+
subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
|
126
|
+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "updates with scripted upsert" do
|
131
|
+
it "should create new documents with upsert content" do
|
132
|
+
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_update', 'upsert' => '{"message": "upsert message"}', 'script_type' => 'file' })
|
133
|
+
subject.register
|
134
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
135
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
136
|
+
insist { r["_source"]["message"] } == 'upsert message'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should create new documents with event/doc as script params" do
|
140
|
+
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_upsert', 'scripted_upsert' => true, 'script_type' => 'file' })
|
141
|
+
subject.register
|
142
|
+
subject.multi_receive([LogStash::Event.new("counter" => 1)])
|
143
|
+
@es.indices.refresh
|
144
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
145
|
+
insist { r["_source"]["counter"] } == 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -43,6 +43,7 @@ describe "Ingest pipeline execution behavior", :integration => true, :version_gr
|
|
43
43
|
|
44
44
|
# register pipeline
|
45
45
|
req = ftw_client.put(ingest_url, :body => apache_logs_pipeline)
|
46
|
+
req.headers["Content-Type"] = "application/json"
|
46
47
|
ftw_client.execute(req)
|
47
48
|
|
48
49
|
#TODO: Use esclient
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require_relative "../../../spec/es_spec_helper"
|
2
|
+
|
3
|
+
describe "Update actions using painless scripts", :integration => true, :update_tests => 'painless', :version_greater_than_equal_to_5x => true do
|
4
|
+
require "logstash/outputs/elasticsearch"
|
5
|
+
|
6
|
+
def get_es_output( options={} )
|
7
|
+
settings = {
|
8
|
+
"manage_template" => true,
|
9
|
+
"index" => "logstash-update",
|
10
|
+
"template_overwrite" => true,
|
11
|
+
"hosts" => get_host_port(),
|
12
|
+
"action" => "update",
|
13
|
+
"script_lang" => "painless"
|
14
|
+
}
|
15
|
+
LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
|
16
|
+
end
|
17
|
+
|
18
|
+
before :each do
|
19
|
+
@es = get_client
|
20
|
+
# Delete all templates first.
|
21
|
+
# Clean ES of data before we start.
|
22
|
+
@es.indices.delete_template(:name => "*")
|
23
|
+
# This can fail if there are no indexes, ignore failure.
|
24
|
+
@es.indices.delete(:index => "*") rescue nil
|
25
|
+
@es.index(
|
26
|
+
:index => 'logstash-update',
|
27
|
+
:type => 'logs',
|
28
|
+
:id => "123",
|
29
|
+
:body => { :message => 'Test', :counter => 1 }
|
30
|
+
)
|
31
|
+
@es.indices.refresh
|
32
|
+
end
|
33
|
+
|
34
|
+
context "scripted updates" do
|
35
|
+
it "should increment a counter with event/doc 'count' variable" do
|
36
|
+
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update', 'script_type' => 'file' })
|
37
|
+
subject.register
|
38
|
+
subject.multi_receive([LogStash::Event.new("count" => 2)])
|
39
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
40
|
+
insist { r["_source"]["counter"] } == 3
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should increment a counter with event/doc '[data][count]' nested variable" do
|
44
|
+
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update_nested', 'script_type' => 'file' })
|
45
|
+
subject.register
|
46
|
+
subject.multi_receive([LogStash::Event.new("data" => { "count" => 3 })])
|
47
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
48
|
+
insist { r["_source"]["counter"] } == 4
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should increment a counter with event/doc 'count' variable with inline script" do
|
52
|
+
subject = get_es_output({
|
53
|
+
'document_id' => "123",
|
54
|
+
'script' => 'ctx._source.counter += params.event.counter',
|
55
|
+
'script_lang' => 'painless',
|
56
|
+
'script_type' => 'inline'
|
57
|
+
})
|
58
|
+
subject.register
|
59
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
60
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
61
|
+
insist { r["_source"]["counter"] } == 4
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should increment a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
65
|
+
subject = get_es_output({
|
66
|
+
'document_id' => "123",
|
67
|
+
'doc_as_upsert' => true,
|
68
|
+
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += params.event.counter; } else { ctx._source.counter = params.event.counter; }',
|
69
|
+
'script_lang' => 'painless',
|
70
|
+
'script_type' => 'inline'
|
71
|
+
})
|
72
|
+
subject.register
|
73
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
74
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
75
|
+
insist { r["_source"]["counter"] } == 4
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should, with new doc, set a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
79
|
+
subject = get_es_output({
|
80
|
+
'document_id' => "456",
|
81
|
+
'doc_as_upsert' => true,
|
82
|
+
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += params.event.counter; } else { ctx._source.counter = params.event.counter; }',
|
83
|
+
'script_lang' => 'painless',
|
84
|
+
'script_type' => 'inline'
|
85
|
+
})
|
86
|
+
subject.register
|
87
|
+
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
88
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
89
|
+
insist { r["_source"]["counter"] } == 3
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should increment a counter with event/doc 'count' variable with indexed script" do
|
93
|
+
@es.put_script lang: 'painless', id: 'indexed_update', body: { script: 'ctx._source.counter += params.event.count' }
|
94
|
+
subject = get_es_output({
|
95
|
+
'document_id' => "123",
|
96
|
+
'script' => 'indexed_update',
|
97
|
+
'script_lang' => 'painless',
|
98
|
+
'script_type' => 'indexed'
|
99
|
+
})
|
100
|
+
subject.register
|
101
|
+
subject.multi_receive([LogStash::Event.new("count" => 4 )])
|
102
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
103
|
+
insist { r["_source"]["counter"] } == 5
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when update with upsert" do
|
108
|
+
it "should create new documents with provided upsert" do
|
109
|
+
subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
|
110
|
+
subject.register
|
111
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
112
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
113
|
+
insist { r["_source"]["message"] } == 'upsert message'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should create new documents with event/doc as upsert" do
|
117
|
+
subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true })
|
118
|
+
subject.register
|
119
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
120
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
121
|
+
insist { r["_source"]["message"] } == 'sample message here'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should fail on documents with event/doc as upsert at external version" do
|
125
|
+
subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
|
126
|
+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "updates with scripted upsert" do
|
131
|
+
it "should create new documents with upsert content" do
|
132
|
+
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_update', 'upsert' => '{"message": "upsert message"}', 'script_type' => 'file' })
|
133
|
+
subject.register
|
134
|
+
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
135
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
136
|
+
insist { r["_source"]["message"] } == 'upsert message'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should create new documents with event/doc as script params" do
|
140
|
+
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_upsert', 'scripted_upsert' => true, 'script_type' => 'file' })
|
141
|
+
subject.register
|
142
|
+
subject.multi_receive([LogStash::Event.new("counter" => 1)])
|
143
|
+
@es.indices.refresh
|
144
|
+
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
145
|
+
insist { r["_source"]["counter"] } == 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "../../../spec/es_spec_helper"
|
2
|
+
require "logstash/outputs/elasticsearch"
|
2
3
|
|
3
4
|
shared_examples "a parent indexer" do
|
4
5
|
let(:index) { 10.times.collect { rand(10).to_s }.join("") }
|
@@ -6,6 +7,9 @@ shared_examples "a parent indexer" do
|
|
6
7
|
let(:event_count) { 10000 + rand(500) }
|
7
8
|
let(:parent) { "not_implemented" }
|
8
9
|
let(:config) { "not_implemented" }
|
10
|
+
let(:default_headers) {
|
11
|
+
{"Content-Type" => "application/json"}
|
12
|
+
}
|
9
13
|
subject { LogStash::Outputs::ElasticSearch.new(config) }
|
10
14
|
|
11
15
|
before do
|
@@ -13,9 +17,9 @@ shared_examples "a parent indexer" do
|
|
13
17
|
index_url = "http://#{get_host_port()}/#{index}"
|
14
18
|
ftw = FTW::Agent.new
|
15
19
|
mapping = { "mappings" => { "#{type}" => { "_parent" => { "type" => "#{type}_parent" } } } }
|
16
|
-
ftw.put!("#{index_url}", :body => mapping.to_json)
|
20
|
+
ftw.put!("#{index_url}", {:body => mapping.to_json, :headers => default_headers})
|
17
21
|
pdoc = { "foo" => "bar" }
|
18
|
-
ftw.put!("#{index_url}/#{type}_parent/test", :body => pdoc.to_json)
|
22
|
+
ftw.put!("#{index_url}/#{type}_parent/test", {:body => pdoc.to_json, :headers => default_headers})
|
19
23
|
|
20
24
|
subject.register
|
21
25
|
subject.multi_receive(event_count.times.map { LogStash::Event.new("link_to" => "test", "message" => "Hello World!", "type" => type) })
|
@@ -32,7 +36,7 @@ shared_examples "a parent indexer" do
|
|
32
36
|
Stud::try(10.times) do
|
33
37
|
query = { "query" => { "has_parent" => { "type" => "#{type}_parent", "query" => { "match" => { "foo" => "bar" } } } } }
|
34
38
|
data = ""
|
35
|
-
response = ftw.post!("#{index_url}/_count", :body => query.to_json)
|
39
|
+
response = ftw.post!("#{index_url}/_count", {:body => query.to_json, :headers => default_headers})
|
36
40
|
response.read_body { |chunk| data << chunk }
|
37
41
|
result = LogStash::Json.load(data)
|
38
42
|
cur_count = result["count"]
|
@@ -38,7 +38,7 @@ describe "pool sniffer", :integration => true do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# We do a more thorough check on these versions because we can more reliably guess the ip
|
41
|
-
describe("Complex sniff parsing ES 5x/2x", :version_greater_than_equal_to_2x => true) do
|
41
|
+
describe("Complex sniff parsing ES 6x/5x/2x", :version_greater_than_equal_to_2x => true) do
|
42
42
|
include_examples("sniff parsing", true)
|
43
43
|
end
|
44
44
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative "../../../spec/es_spec_helper"
|
2
2
|
|
3
|
-
describe "Update actions", :integration => true, :version_greater_than_equal_to_2x => true do
|
3
|
+
describe "Update actions without scripts", :integration => true, :version_greater_than_equal_to_2x => true do
|
4
4
|
require "logstash/outputs/elasticsearch"
|
5
5
|
|
6
6
|
def get_es_output( options={} )
|
@@ -9,8 +9,7 @@ describe "Update actions", :integration => true, :version_greater_than_equal_to_
|
|
9
9
|
"index" => "logstash-update",
|
10
10
|
"template_overwrite" => true,
|
11
11
|
"hosts" => get_host_port(),
|
12
|
-
"action" => "update"
|
13
|
-
"script_lang" => "groovy"
|
12
|
+
"action" => "update"
|
14
13
|
}
|
15
14
|
LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
|
16
15
|
end
|
@@ -90,79 +89,6 @@ describe "Update actions", :integration => true, :version_greater_than_equal_to_
|
|
90
89
|
|
91
90
|
end
|
92
91
|
|
93
|
-
context "when using script" do
|
94
|
-
it "should increment a counter with event/doc 'count' variable" do
|
95
|
-
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update', 'script_type' => 'file' })
|
96
|
-
subject.register
|
97
|
-
subject.multi_receive([LogStash::Event.new("count" => 2)])
|
98
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
99
|
-
insist { r["_source"]["counter"] } == 3
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should increment a counter with event/doc '[data][count]' nested variable" do
|
103
|
-
subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update_nested', 'script_type' => 'file' })
|
104
|
-
subject.register
|
105
|
-
subject.multi_receive([LogStash::Event.new("data" => { "count" => 3 })])
|
106
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
107
|
-
insist { r["_source"]["counter"] } == 4
|
108
|
-
end
|
109
|
-
|
110
|
-
it "should increment a counter with event/doc 'count' variable with inline script" do
|
111
|
-
subject = get_es_output({
|
112
|
-
'document_id' => "123",
|
113
|
-
'script' => 'ctx._source.counter += event["counter"]',
|
114
|
-
'script_lang' => 'groovy',
|
115
|
-
'script_type' => 'inline'
|
116
|
-
})
|
117
|
-
subject.register
|
118
|
-
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
119
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
120
|
-
insist { r["_source"]["counter"] } == 4
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should increment a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
124
|
-
subject = get_es_output({
|
125
|
-
'document_id' => "123",
|
126
|
-
'doc_as_upsert' => true,
|
127
|
-
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["counter"]; } else { ctx._source.counter = event["counter"]; }',
|
128
|
-
'script_lang' => 'groovy',
|
129
|
-
'script_type' => 'inline'
|
130
|
-
})
|
131
|
-
subject.register
|
132
|
-
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
133
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
134
|
-
insist { r["_source"]["counter"] } == 4
|
135
|
-
end
|
136
|
-
|
137
|
-
it "should, with new doc, set a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
|
138
|
-
subject = get_es_output({
|
139
|
-
'document_id' => "456",
|
140
|
-
'doc_as_upsert' => true,
|
141
|
-
'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["count"]; } else { ctx._source.counter = event["count"]; }',
|
142
|
-
'script_lang' => 'groovy',
|
143
|
-
'script_type' => 'inline'
|
144
|
-
})
|
145
|
-
subject.register
|
146
|
-
subject.multi_receive([LogStash::Event.new("counter" => 3 )])
|
147
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
148
|
-
insist { r["_source"]["counter"] } == 3
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should increment a counter with event/doc 'count' variable with indexed script" do
|
152
|
-
@es.put_script lang: 'groovy', id: 'indexed_update', body: { script: 'ctx._source.counter += event["count"]' }
|
153
|
-
subject = get_es_output({
|
154
|
-
'document_id' => "123",
|
155
|
-
'script' => 'indexed_update',
|
156
|
-
'script_lang' => 'groovy',
|
157
|
-
'script_type' => 'indexed'
|
158
|
-
})
|
159
|
-
subject.register
|
160
|
-
subject.multi_receive([LogStash::Event.new("count" => 4 )])
|
161
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
|
162
|
-
insist { r["_source"]["counter"] } == 5
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
92
|
context "when update with upsert" do
|
167
93
|
it "should create new documents with provided upsert" do
|
168
94
|
subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
|
@@ -184,24 +110,5 @@ describe "Update actions", :integration => true, :version_greater_than_equal_to_
|
|
184
110
|
subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
|
185
111
|
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
|
186
112
|
end
|
187
|
-
|
188
|
-
context "when using script" do
|
189
|
-
it "should create new documents with upsert content" do
|
190
|
-
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_update', 'upsert' => '{"message": "upsert message"}', 'script_type' => 'file' })
|
191
|
-
subject.register
|
192
|
-
subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
|
193
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
194
|
-
insist { r["_source"]["message"] } == 'upsert message'
|
195
|
-
end
|
196
|
-
|
197
|
-
it "should create new documents with event/doc as script params" do
|
198
|
-
subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_upsert', 'scripted_upsert' => true, 'script_type' => 'file' })
|
199
|
-
subject.register
|
200
|
-
subject.multi_receive([LogStash::Event.new("counter" => 1)])
|
201
|
-
@es.indices.refresh
|
202
|
-
r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
|
203
|
-
insist { r["_source"]["counter"] } == 1
|
204
|
-
end
|
205
|
-
end
|
206
113
|
end
|
207
114
|
end
|
@@ -121,6 +121,20 @@ describe LogStash::Outputs::ElasticSearch::HttpClient do
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
+
describe "get" do
|
125
|
+
subject { described_class.new(base_options) }
|
126
|
+
let(:body) { "foobar" }
|
127
|
+
let(:path) { "/hello-id" }
|
128
|
+
let(:get_response) {
|
129
|
+
double("response", :body => LogStash::Json::dump( { "body" => body }))
|
130
|
+
}
|
131
|
+
|
132
|
+
it "returns the hash response" do
|
133
|
+
expect(subject.pool).to receive(:get).with(path, nil).and_return([nil, get_response])
|
134
|
+
expect(subject.get(path)["body"]).to eq(body)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
124
138
|
describe "join_bulk_responses" do
|
125
139
|
subject { described_class.new(base_options) }
|
126
140
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.2.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +213,7 @@ files:
|
|
213
213
|
- lib/logstash/outputs/elasticsearch/common_configs.rb
|
214
214
|
- lib/logstash/outputs/elasticsearch/elasticsearch-template-es2x.json
|
215
215
|
- lib/logstash/outputs/elasticsearch/elasticsearch-template-es5x.json
|
216
|
+
- lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json
|
216
217
|
- lib/logstash/outputs/elasticsearch/http_client.rb
|
217
218
|
- lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb
|
218
219
|
- lib/logstash/outputs/elasticsearch/http_client/pool.rb
|
@@ -222,16 +223,21 @@ files:
|
|
222
223
|
- spec/es_spec_helper.rb
|
223
224
|
- spec/fixtures/htpasswd
|
224
225
|
- spec/fixtures/nginx_reverse_proxy.conf
|
225
|
-
- spec/fixtures/scripts/scripted_update.groovy
|
226
|
-
- spec/fixtures/scripts/scripted_update_nested.groovy
|
227
|
-
- spec/fixtures/scripts/scripted_upsert.groovy
|
226
|
+
- spec/fixtures/scripts/groovy/scripted_update.groovy
|
227
|
+
- spec/fixtures/scripts/groovy/scripted_update_nested.groovy
|
228
|
+
- spec/fixtures/scripts/groovy/scripted_upsert.groovy
|
229
|
+
- spec/fixtures/scripts/painless/scripted_update.painless
|
230
|
+
- spec/fixtures/scripts/painless/scripted_update_nested.painless
|
231
|
+
- spec/fixtures/scripts/painless/scripted_upsert.painless
|
228
232
|
- spec/integration/outputs/compressed_indexing_spec.rb
|
229
233
|
- spec/integration/outputs/create_spec.rb
|
230
234
|
- spec/integration/outputs/delete_spec.rb
|
235
|
+
- spec/integration/outputs/groovy_update_spec.rb
|
231
236
|
- spec/integration/outputs/index_spec.rb
|
232
237
|
- spec/integration/outputs/index_version_spec.rb
|
238
|
+
- spec/integration/outputs/ingest_pipeline_spec.rb
|
239
|
+
- spec/integration/outputs/painless_update_spec.rb
|
233
240
|
- spec/integration/outputs/parent_spec.rb
|
234
|
-
- spec/integration/outputs/pipeline_spec.rb
|
235
241
|
- spec/integration/outputs/retry_spec.rb
|
236
242
|
- spec/integration/outputs/routing_spec.rb
|
237
243
|
- spec/integration/outputs/sniffer_spec.rb
|
@@ -277,16 +283,21 @@ test_files:
|
|
277
283
|
- spec/es_spec_helper.rb
|
278
284
|
- spec/fixtures/htpasswd
|
279
285
|
- spec/fixtures/nginx_reverse_proxy.conf
|
280
|
-
- spec/fixtures/scripts/scripted_update.groovy
|
281
|
-
- spec/fixtures/scripts/scripted_update_nested.groovy
|
282
|
-
- spec/fixtures/scripts/scripted_upsert.groovy
|
286
|
+
- spec/fixtures/scripts/groovy/scripted_update.groovy
|
287
|
+
- spec/fixtures/scripts/groovy/scripted_update_nested.groovy
|
288
|
+
- spec/fixtures/scripts/groovy/scripted_upsert.groovy
|
289
|
+
- spec/fixtures/scripts/painless/scripted_update.painless
|
290
|
+
- spec/fixtures/scripts/painless/scripted_update_nested.painless
|
291
|
+
- spec/fixtures/scripts/painless/scripted_upsert.painless
|
283
292
|
- spec/integration/outputs/compressed_indexing_spec.rb
|
284
293
|
- spec/integration/outputs/create_spec.rb
|
285
294
|
- spec/integration/outputs/delete_spec.rb
|
295
|
+
- spec/integration/outputs/groovy_update_spec.rb
|
286
296
|
- spec/integration/outputs/index_spec.rb
|
287
297
|
- spec/integration/outputs/index_version_spec.rb
|
298
|
+
- spec/integration/outputs/ingest_pipeline_spec.rb
|
299
|
+
- spec/integration/outputs/painless_update_spec.rb
|
288
300
|
- spec/integration/outputs/parent_spec.rb
|
289
|
-
- spec/integration/outputs/pipeline_spec.rb
|
290
301
|
- spec/integration/outputs/retry_spec.rb
|
291
302
|
- spec/integration/outputs/routing_spec.rb
|
292
303
|
- spec/integration/outputs/sniffer_spec.rb
|