logstash-output-http 5.0.1 → 5.1.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
  SHA1:
3
- metadata.gz: ddd34eaab5f5f023138eede5762b6911c6542be9
4
- data.tar.gz: ab1aec99d160c6dcd84fe624d5d4274fa0840dfd
3
+ metadata.gz: ed1975dd9a23d8a355ca14ccd0d191d387620356
4
+ data.tar.gz: d4ce66fe7f7c0b4e5396f819a70aeb62292be625
5
5
  SHA512:
6
- metadata.gz: 2e5d6443d21b3caf9172a53c6469a4ba9cd8351f3c62e10ecc2b905eabf2710427b63938d0b56e66245487e59486c6dac05e1d1a5a5825c2692914bd0a8b4892
7
- data.tar.gz: 6ae047e197b2e1ff442ef460d49e22f40b5746c0cde155d2752778d23836fe9fae4a69712c38377d5a3780b94fbb52ce70aeea96b7ec66babb6b1bbec4f0da6b
6
+ metadata.gz: d393ce2604784a67dcdedd1196650054cc32e246e16fb13fc93638941fbf6f0dffad804a758b9b99bd87ebefa16ed194b3e5558c52bf92b403c54af1fc72cd70
7
+ data.tar.gz: 70237b74bcdbeaeb2a0bd482f07189faf3c3f9dedda59226ca29086f9967eb7cf93dab8caecfb10e47093b508ca9aa8d2fc5013fec3f3b84feadca79dec6cabb
@@ -1,3 +1,6 @@
1
+ ## 5.1.0
2
+ - Adding a new option `http_compression` for sending compressed payload with the `Content-Encoding: gzip` header to the configured http endpoint #66
3
+
1
4
  ## 5.0.1
2
5
  - Fix some documentation issues
3
6
 
@@ -48,6 +48,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
48
48
  | <<plugins-{type}s-{plugin}-follow_redirects>> |<<boolean,boolean>>|No
49
49
  | <<plugins-{type}s-{plugin}-format>> |<<string,string>>, one of `["json", "form", "message"]`|No
50
50
  | <<plugins-{type}s-{plugin}-headers>> |<<hash,hash>>|No
51
+ | <<plugins-{type}s-{plugin}-http_compression>> |<<boolean,boolean>>|No
51
52
  | <<plugins-{type}s-{plugin}-http_method>> |<<string,string>>, one of `["put", "post", "patch", "delete", "get", "head"]`|Yes
52
53
  | <<plugins-{type}s-{plugin}-ignorable_codes>> |<<number,number>>|No
53
54
  | <<plugins-{type}s-{plugin}-keepalive>> |<<boolean,boolean>>|No
@@ -172,6 +173,15 @@ Otherwise, the event is sent as json.
172
173
  Custom headers to use
173
174
  format is `headers => ["X-My-Header", "%{host}"]`
174
175
 
176
+ [id="plugins-{type}s-{plugin}-http_compression"]
177
+ ===== `http_compression`
178
+
179
+ * Value type is <<boolean,boolean>>
180
+ * Default value is `false`
181
+
182
+ Enable request compression support. With this enabled the plugin will compress
183
+ http requests using gzip.
184
+
175
185
  [id="plugins-{type}s-{plugin}-http_method"]
176
186
  ===== `http_method`
177
187
 
@@ -4,6 +4,7 @@ require "logstash/namespace"
4
4
  require "logstash/json"
5
5
  require "uri"
6
6
  require "logstash/plugin_mixins/http_client"
7
+ require "zlib"
7
8
 
8
9
  class LogStash::Outputs::Http < LogStash::Outputs::Base
9
10
  include LogStash::PluginMixins::HttpClient
@@ -80,6 +81,9 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base
80
81
  # Otherwise, the event is sent as json.
81
82
  config :format, :validate => ["json", "form", "message"], :default => "json"
82
83
 
84
+ # Set this to true if you want to enable gzip compression for your http requests
85
+ config :http_compression, :validate => :boolean, :default => false
86
+
83
87
  config :message, :validate => :string
84
88
 
85
89
  def register
@@ -196,6 +200,12 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base
196
200
  url = event.sprintf(@url)
197
201
  headers = event_headers(event)
198
202
 
203
+ # Compress the body and add appropriate header
204
+ if @http_compression == true
205
+ headers["Content-Encoding"] = "gzip"
206
+ body = gzip(body)
207
+ end
208
+
199
209
  # Create an async request
200
210
  request = client.background.send(@http_method, url, :body => body, :headers => headers)
201
211
 
@@ -300,6 +310,16 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base
300
310
  end
301
311
  end
302
312
 
313
+ # gzip data
314
+ def gzip(data)
315
+ gz = StringIO.new
316
+ gz.set_encoding("BINARY")
317
+ z = Zlib::GzipWriter.new(gz)
318
+ z.write(data)
319
+ z.close
320
+ gz.string
321
+ end
322
+
303
323
  def convert_mapping(mapping, event)
304
324
  if mapping.is_a?(Hash)
305
325
  mapping.reduce({}) do |acc, kv|
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-http'
3
- s.version = '5.0.1'
3
+ s.version = '5.1.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "This output lets you `PUT` or `POST` events to a generic HTTP(S) endpoint"
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"
@@ -3,6 +3,7 @@ require "logstash/outputs/http"
3
3
  require "logstash/codecs/plain"
4
4
  require "thread"
5
5
  require "sinatra"
6
+ require_relative "../supports/compressed_requests"
6
7
 
7
8
  PORT = rand(65535-1024) + 1025
8
9
 
@@ -16,8 +17,10 @@ end
16
17
  #
17
18
  # == Sinatra (v1.4.6) has taken the stage on 51572 for development with backup from WEBrick
18
19
  # == Sinatra has ended his set (crowd applauds)
19
-
20
+ #
20
21
  class TestApp < Sinatra::Base
22
+ # on the fly uncompress gzip content
23
+ use CompressedRequests
21
24
 
22
25
  # disable WEBrick logging
23
26
  def self.server_settings
@@ -38,11 +41,11 @@ class TestApp < Sinatra::Base
38
41
  def self.last_request
39
42
  @last_request
40
43
  end
41
-
44
+
42
45
  def self.retry_fail_count=(count)
43
46
  @retry_fail_count = count
44
47
  end
45
-
48
+
46
49
  def self.retry_fail_count()
47
50
  @retry_fail_count
48
51
  end
@@ -56,10 +59,10 @@ class TestApp < Sinatra::Base
56
59
  self.class.last_request = request
57
60
  [400, "YUP"]
58
61
  end
59
-
62
+
60
63
  multiroute(%w(get post put patch delete), "/retry") do
61
64
  self.class.last_request = request
62
-
65
+
63
66
  if self.class.retry_fail_count > 0
64
67
  self.class.retry_fail_count -= 1
65
68
  [429, "Will succeed in #{self.class.retry_fail_count}"]
@@ -80,7 +83,7 @@ RSpec.configure do |config|
80
83
  app.run!(opts) do |server|
81
84
  queue.push("started")
82
85
  end
83
- rescue => e
86
+ rescue => e
84
87
  puts "Error in webserver thread #{e}"
85
88
  # ignore
86
89
  end
@@ -158,7 +161,7 @@ describe LogStash::Outputs::Http do
158
161
  expect(subject).to have_received(:log_failure).with(any_args)
159
162
  end
160
163
  end
161
-
164
+
162
165
  context "with ignorable failing requests" do
163
166
  let(:url) { "http://localhost:#{port}/bad"}
164
167
  let(:verb_behavior_config) { super.merge("ignorable_codes" => [400]) }
@@ -171,7 +174,7 @@ describe LogStash::Outputs::Http do
171
174
  expect(subject).not_to have_received(:log_failure).with(any_args)
172
175
  end
173
176
  end
174
-
177
+
175
178
  context "with retryable failing requests" do
176
179
  let(:url) { "http://localhost:#{port}/retry"}
177
180
 
@@ -184,12 +187,12 @@ describe LogStash::Outputs::Http do
184
187
  it "should log a failure 2 times" do
185
188
  expect(subject).to have_received(:log_failure).with(any_args).twice
186
189
  end
187
-
190
+
188
191
  it "should make three total requests" do
189
192
  expect(subject).to have_received(:send_event).exactly(3).times
190
193
  end
191
- end
192
-
194
+ end
195
+
193
196
  end
194
197
  end
195
198
 
@@ -225,7 +228,8 @@ describe LogStash::Outputs::Http do
225
228
  end
226
229
  end
227
230
 
228
- describe "integration tests" do
231
+ shared_examples "integration tests" do
232
+ let(:base_config) { {} }
229
233
  let(:url) { "http://localhost:#{port}/good" }
230
234
  let(:event) {
231
235
  LogStash::Event.new("foo" => "bar", "baz" => "bot", "user" => "McBest")
@@ -239,7 +243,7 @@ describe LogStash::Outputs::Http do
239
243
 
240
244
  describe "sending with the default (JSON) config" do
241
245
  let(:config) {
242
- {"url" => url, "http_method" => "post", "pool_max" => 1}
246
+ base_config.merge({"url" => url, "http_method" => "post", "pool_max" => 1})
243
247
  }
244
248
  let(:expected_body) { LogStash::Json.dump(event) }
245
249
  let(:expected_content_type) { "application/json" }
@@ -249,7 +253,7 @@ describe LogStash::Outputs::Http do
249
253
 
250
254
  describe "sending the event as a form" do
251
255
  let(:config) {
252
- {"url" => url, "http_method" => "post", "pool_max" => 1, "format" => "form"}
256
+ base_config.merge({"url" => url, "http_method" => "post", "pool_max" => 1, "format" => "form"})
253
257
  }
254
258
  let(:expected_body) { subject.send(:encode, event.to_hash) }
255
259
  let(:expected_content_type) { "application/x-www-form-urlencoded" }
@@ -259,7 +263,7 @@ describe LogStash::Outputs::Http do
259
263
 
260
264
  describe "sending the event as a message" do
261
265
  let(:config) {
262
- {"url" => url, "http_method" => "post", "pool_max" => 1, "format" => "message", "message" => "%{foo} AND %{baz}"}
266
+ base_config.merge({"url" => url, "http_method" => "post", "pool_max" => 1, "format" => "message", "message" => "%{foo} AND %{baz}"})
263
267
  }
264
268
  let(:expected_body) { "#{event.get("foo")} AND #{event.get("baz")}" }
265
269
  let(:expected_content_type) { "text/plain" }
@@ -269,7 +273,7 @@ describe LogStash::Outputs::Http do
269
273
 
270
274
  describe "sending a mapped event" do
271
275
  let(:config) {
272
- {"url" => url, "http_method" => "post", "pool_max" => 1, "mapping" => {"blah" => "X %{foo}"} }
276
+ base_config.merge({"url" => url, "http_method" => "post", "pool_max" => 1, "mapping" => {"blah" => "X %{foo}"} })
273
277
  }
274
278
  let(:expected_body) { LogStash::Json.dump("blah" => "X #{event.get("foo")}") }
275
279
  let(:expected_content_type) { "application/json" }
@@ -279,7 +283,7 @@ describe LogStash::Outputs::Http do
279
283
 
280
284
  describe "sending a mapped, nested event" do
281
285
  let(:config) {
282
- {
286
+ base_config.merge({
283
287
  "url" => url,
284
288
  "http_method" => "post",
285
289
  "pool_max" => 1,
@@ -292,7 +296,7 @@ describe LogStash::Outputs::Http do
292
296
  "user" => "Z %{user}"
293
297
  }]
294
298
  }
295
- }
299
+ })
296
300
  }
297
301
  let(:expected_body) {
298
302
  LogStash::Json.dump({
@@ -310,4 +314,14 @@ describe LogStash::Outputs::Http do
310
314
  include_examples("a received event")
311
315
  end
312
316
  end
317
+
318
+ describe "integration test without gzip compression" do
319
+ include_examples("integration tests")
320
+ end
321
+
322
+ describe "integration test with gzip compression" do
323
+ include_examples("integration tests") do
324
+ let(:base_config) { { "http_compression" => true } }
325
+ end
326
+ end
313
327
  end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ #
3
+ # based on relistan's rack handler
4
+ # out of the box rack only gives use the rack deflater handler to return compressed
5
+ # response, this gist offer the inverse and should work on all rack based app like sinatra or rails.
6
+ #
7
+ # original source: https://gist.github.com/relistan/2109707
8
+ require "zlib"
9
+
10
+ class CompressedRequests
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ def encoding_handled?(env)
16
+ ['gzip', 'deflate'].include? env['HTTP_CONTENT_ENCODING']
17
+ end
18
+
19
+ def call(env)
20
+ if encoding_handled?(env)
21
+ extracted = decode(env['rack.input'], env['HTTP_CONTENT_ENCODING'])
22
+
23
+ env.delete('HTTP_CONTENT_ENCODING')
24
+ env['CONTENT_LENGTH'] = extracted.bytesize
25
+ env['rack.input'] = StringIO.new(extracted)
26
+ end
27
+
28
+ status, headers, response = @app.call(env)
29
+ return [status, headers, response]
30
+ end
31
+
32
+ def decode(input, content_encoding)
33
+ case content_encoding
34
+ when 'gzip' then Zlib::GzipReader.new(input).read
35
+ when 'deflate' then Zlib::Inflate.inflate(input.read)
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-16 00:00:00.000000000 Z
11
+ date: 2017-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,7 @@ files:
108
108
  - lib/logstash/outputs/http.rb
109
109
  - logstash-output-http.gemspec
110
110
  - spec/outputs/http_spec.rb
111
+ - spec/supports/compressed_requests.rb
111
112
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
112
113
  licenses:
113
114
  - Apache License (2.0)
@@ -136,3 +137,4 @@ specification_version: 4
136
137
  summary: This output lets you `PUT` or `POST` events to a generic HTTP(S) endpoint
137
138
  test_files:
138
139
  - spec/outputs/http_spec.rb
140
+ - spec/supports/compressed_requests.rb