logstash-filter-elasticsearch 3.9.5 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c42fd982d06ded966f625f3665120e64edc9b8585a2e5086214a14dd41f6e2a
4
- data.tar.gz: 8411efb4ab1747adf5d824c39d098ccc64660c657916920b1bb4a194e8baf8ef
3
+ metadata.gz: 8e04ff9ca7407b8404764623b42f7ce8e754fe9ceafc6bde7cc064bc13c30723
4
+ data.tar.gz: 3b317df7d5bc1b11c912e8f9d6ec14c2ef260fa975412f2ebbf2baf84da547ba
5
5
  SHA512:
6
- metadata.gz: c7be68bcfcd60db5d7b7c76ae484d382f8efb470abe5c33393330b1a2344b8b01e79f6a02038b2f37032783bd6abc045f44a12c504cac8b2ca1d534d110872a9
7
- data.tar.gz: 57d1ab30bb38a717d3f1e8da8dc9b70fb2b1873bb8e2e482b67a0ae2396a32948842233d586cf8ea29831280ad4af7f284f73e5eef5bf0027a9f2040588cca4b
6
+ metadata.gz: 6dd245e044d1c06882885e776ba64463c1dbfc93d3c80ad03ad4009b6a3b6246e5a166dc11c09cafb58f2b05b3a6e485741aef6a2137edc227081b1e06bf9e3c
7
+ data.tar.gz: b9b211e1bf50bcb18d028e5322e78eaa3e113a034550eaae4ee3550b941e74235b5ed672417759eb35709e46693f7f602b8106ce13beb17bc6937eacbd991514
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 3.10.0
2
+ - Feat: add user-agent header passed to the Elasticsearch HTTP connection [#152](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/152)
3
+
1
4
  ## 3.9.5
2
5
  - Fixed SSL handshake hang indefinitely with proxy setup [#151](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/151)
3
6
 
@@ -16,10 +16,12 @@ module LogStash
16
16
  password = options.fetch(:password, nil)
17
17
  api_key = options.fetch(:api_key, nil)
18
18
  proxy = options.fetch(:proxy, nil)
19
+ user_agent = options[:user_agent]
19
20
 
20
21
  transport_options = {:headers => {}}
21
22
  transport_options[:headers].merge!(setup_basic_auth(user, password))
22
23
  transport_options[:headers].merge!(setup_api_key(api_key))
24
+ transport_options[:headers].merge!({ 'user-agent' => "#{user_agent}" })
23
25
 
24
26
  logger.warn "Supplied proxy setting (proxy => '') has no effect" if @proxy.eql?('')
25
27
  transport_options[:proxy] = proxy.to_s if proxy && !proxy.eql?('')
@@ -20,7 +20,18 @@ if es_client_version >= Gem::Version.new('7.2') && es_client_version < Gem::Vers
20
20
  def apply_headers(request_options, options)
21
21
  headers = (options && options[:headers]) || {}
22
22
  headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE
23
- headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || user_agent_header
23
+
24
+ # this code is necessary to grab the correct user-agent header
25
+ # when this method is invoked with apply_headers(@request_options, options)
26
+ # from https://github.com/elastic/elasticsearch-ruby/blob/v7.14.0/elasticsearch-transport/lib/elasticsearch/transport/transport/http/manticore.rb#L113-L114
27
+ transport_user_agent = nil
28
+ if (options && options[:transport_options] && options[:transport_options][:headers])
29
+ transport_headers = {}
30
+ transport_headers = options[:transport_options][:headers]
31
+ transport_user_agent = find_value(transport_headers, USER_AGENT_REGEX)
32
+ end
33
+
34
+ headers[USER_AGENT_STR] = transport_user_agent || find_value(headers, USER_AGENT_REGEX) || user_agent_header
24
35
  headers[ACCEPT_ENCODING] = GZIP if use_compression?
25
36
  (request_options[:headers] ||= {}).merge!(headers) # this line was changed
26
37
  end
@@ -176,6 +176,19 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
176
176
  end
177
177
  end # def filter
178
178
 
179
+ # public only to be reuse in testing
180
+ def prepare_user_agent
181
+ os_name = java.lang.System.getProperty('os.name')
182
+ os_version = java.lang.System.getProperty('os.version')
183
+ os_arch = java.lang.System.getProperty('os.arch')
184
+ jvm_vendor = java.lang.System.getProperty('java.vendor')
185
+ jvm_version = java.lang.System.getProperty('java.version')
186
+
187
+ plugin_version = Gem.loaded_specs['logstash-filter-elasticsearch'].version
188
+ # example: logstash/7.14.1 (OS=Linux-5.4.0-84-generic-amd64; JVM=AdoptOpenJDK-11.0.11) logstash-output-elasticsearch/11.0.1
189
+ "logstash/#{LOGSTASH_VERSION} (OS=#{os_name}-#{os_version}-#{os_arch}; JVM=#{jvm_vendor}-#{jvm_version}) logstash-#{@plugin_type}-#{config_name}/#{plugin_version}"
190
+ end
191
+
179
192
  private
180
193
 
181
194
  def client_options
@@ -192,7 +205,11 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
192
205
  def new_client
193
206
  # NOTE: could pass cloud-id/cloud-auth to client but than we would need to be stricter on ES version requirement
194
207
  # and also LS parsing might differ from ES client's parsing so for consistency we do not pass cloud options ...
195
- LogStash::Filters::ElasticsearchClient.new(@logger, @hosts, client_options)
208
+ opts = client_options
209
+
210
+ opts[:user_agent] = prepare_user_agent
211
+
212
+ LogStash::Filters::ElasticsearchClient.new(@logger, @hosts, opts)
196
213
  end
197
214
 
198
215
  def get_client
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-elasticsearch'
4
- s.version = '3.9.5'
4
+ s.version = '3.10.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Copies fields from previous log events in Elasticsearch to current events "
7
7
  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"
@@ -23,6 +23,8 @@ Gem::Specification.new do |s|
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
24
  s.add_runtime_dependency 'elasticsearch', ">= 5.0.5" # LS >= 6.7 and < 7.14 all used version 5.0.5
25
25
  s.add_runtime_dependency 'manticore', ">= 0.7.1"
26
+ s.add_development_dependency 'cabin', ['~> 0.6']
27
+ s.add_development_dependency 'webrick'
26
28
 
27
29
  s.add_development_dependency 'logstash-devutils'
28
30
  end
@@ -3,6 +3,9 @@ require "logstash/devutils/rspec/spec_helper"
3
3
  require "logstash/plugin"
4
4
  require "logstash/filters/elasticsearch"
5
5
  require "logstash/json"
6
+ require "cabin"
7
+ require "webrick"
8
+ require "uri"
6
9
 
7
10
  describe LogStash::Filters::Elasticsearch do
8
11
 
@@ -291,6 +294,112 @@ describe LogStash::Filters::Elasticsearch do
291
294
  end
292
295
  end
293
296
 
297
+ class StoppableServer
298
+
299
+ attr_reader :port
300
+
301
+ def initialize()
302
+ queue = Queue.new
303
+ @first_req_waiter = java.util.concurrent.CountDownLatch.new(1)
304
+ @first_request = nil
305
+
306
+ @t = java.lang.Thread.new(
307
+ proc do
308
+ begin
309
+ @server = WEBrick::HTTPServer.new :Port => 0, :DocumentRoot => ".",
310
+ :Logger => Cabin::Channel.get, # silence WEBrick logging
311
+ :StartCallback => Proc.new {
312
+ queue.push("started")
313
+ }
314
+ @port = @server.config[:Port]
315
+ @server.mount_proc '/' do |req, res|
316
+ res.body = '''
317
+ {
318
+ "name": "ce7ccfb438e8",
319
+ "cluster_name": "docker-cluster",
320
+ "cluster_uuid": "DyR1hN03QvuCWXRy3jtb0g",
321
+ "version": {
322
+ "number": "7.13.1",
323
+ "build_flavor": "default",
324
+ "build_type": "docker",
325
+ "build_hash": "9a7758028e4ea59bcab41c12004603c5a7dd84a9",
326
+ "build_date": "2021-05-28T17:40:59.346932922Z",
327
+ "build_snapshot": false,
328
+ "lucene_version": "8.8.2",
329
+ "minimum_wire_compatibility_version": "6.8.0",
330
+ "minimum_index_compatibility_version": "6.0.0-beta1"
331
+ },
332
+ "tagline": "You Know, for Search"
333
+ }
334
+ '''
335
+ res.status = 200
336
+ res['Content-Type'] = 'application/json'
337
+ @first_request = req
338
+ @first_req_waiter.countDown()
339
+ end
340
+
341
+ @server.start
342
+ rescue => e
343
+ puts "Error in webserver thread #{e}"
344
+ # ignore
345
+ end
346
+ end
347
+ )
348
+ @t.daemon = true
349
+ @t.start
350
+ queue.pop # blocks until the server is up
351
+ end
352
+
353
+ def stop
354
+ @server.shutdown
355
+ end
356
+
357
+ def wait_receive_request
358
+ @first_req_waiter.await(2, java.util.concurrent.TimeUnit::SECONDS)
359
+ @first_request
360
+ end
361
+ end
362
+
363
+ describe "user-agent header" do
364
+ let!(:webserver) { StoppableServer.new } # webserver must be started before the call, so no lazy "let"
365
+
366
+ after :each do
367
+ webserver.stop
368
+ end
369
+
370
+ it "server should be started" do
371
+ require 'net/http'
372
+ response = nil
373
+ Net::HTTP.start('localhost', webserver.port) {|http|
374
+ response = http.request_get('/')
375
+ }
376
+ expect(response.code.to_i).to eq(200)
377
+ end
378
+
379
+ context "used by plugin" do
380
+ let(:config) do
381
+ {
382
+ "hosts" => ["localhost:#{webserver.port}"],
383
+ "query" => "response: 404",
384
+ "fields" => { "response" => "code" },
385
+ "docinfo_fields" => { "_index" => "es_index" },
386
+ "aggregation_fields" => { "bytes_avg" => "bytes_avg_ls_field" }
387
+ }
388
+ end
389
+ let(:plugin) { described_class.new(config) }
390
+ let(:event) { LogStash::Event.new({}) }
391
+
392
+ it "client should sent the expect user-agent" do
393
+ plugin.register
394
+
395
+ request = webserver.wait_receive_request
396
+
397
+ expect(request.header['user-agent'].size).to eq(1)
398
+ expect(request.header['user-agent'][0]).to match(/logstash\/\d*\.\d*\.\d* \(OS=.*; JVM=.*\) logstash-filter-elasticsearch\/\d*\.\d*\.\d*/)
399
+ end
400
+ end
401
+ end
402
+
294
403
  describe "client" do
295
404
  let(:config) do
296
405
  {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.5
4
+ version: 3.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-20 00:00:00.000000000 Z
11
+ date: 2021-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -58,6 +58,34 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 0.7.1
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0.6'
67
+ name: cabin
68
+ prerelease: false
69
+ type: :development
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.6'
75
+ - !ruby/object:Gem::Dependency
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ name: webrick
82
+ prerelease: false
83
+ type: :development
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
61
89
  - !ruby/object:Gem::Dependency
62
90
  requirement: !ruby/object:Gem::Requirement
63
91
  requirements: