logstash-output-faye 2.2.0 → 3.0.0

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
  SHA1:
3
- metadata.gz: c84a8228af88478051f9d33450c58d8cb331f7a9
4
- data.tar.gz: 5321b905941a648b842dcf3267a70a4164f08c15
3
+ metadata.gz: e9c4c6132f6005917ee6a4849af20dfd63237066
4
+ data.tar.gz: 34c5394325a6af71ed5b1bb28e8be2e9146a7933
5
5
  SHA512:
6
- metadata.gz: a9a960a36ac96bcb68e8bab72d27d91583853a2806114f4508548bc20362e2b3c2ffde554e58fd51e2c1ff4754d3a8f81256a1e2bede631252ceb6f34b641692
7
- data.tar.gz: ebd9f5caaf0114f064da65cfc91d40cc6e86ed6dc3368faac1b200aac876c3f5bc43c60fc5818d34115393d55a230d9c8023d9879c36f99624fd4e3bbb47f2ef
6
+ metadata.gz: 5e75162f94bbb426e00b115531b963e41000b5ffbd2de5c07f26fe599787bca8d080c8c0484cf5980bb744fb9a8b5b7a2f7ca3eb9d30f2fe8af3d3dd6df80939
7
+ data.tar.gz: 9b5a9024fa5ceb6fa1ab3ed75b5a2c87e7c25a298011e09c78384dd04fcd3b6211f7669413fbfb215bf3cb43a1b1839694632dd0eb4679ceccc46b49dc325e44
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 3.0.0
2
+ - New strukture from current http-plugin
3
+
1
4
  ## 2.2.0
2
5
  - Changed dependency to new logstash-core-plugin-api
3
6
 
@@ -1,15 +1,23 @@
1
1
  # encoding: utf-8
2
-
3
- require "logstash/namespace"
4
2
  require "logstash/outputs/base"
5
- require 'json'
6
- require 'pry'
3
+ require "logstash/namespace"
4
+ require "logstash/json"
5
+ require "uri"
6
+ require "logstash/plugin_mixins/http_client"
7
7
 
8
- # File output.
9
- #
10
- # Write events to files on disk. You can use fields from the
11
- # event as parts of the filename.
12
8
  class LogStash::Outputs::Faye < LogStash::Outputs::Base
9
+ include LogStash::PluginMixins::HttpClient
10
+
11
+ # This output lets you send events to a
12
+ # generic HTTP(S) endpoint
13
+ #
14
+ # This output will execute up to 'pool_max' requests in parallel for performance.
15
+ # Consider this when tuning this plugin for performance.
16
+ #
17
+ # Additionally, note that when parallel execution is used strict ordering of events is not
18
+ # guaranteed!
19
+ #
20
+ # Beware, this gem does not yet support codecs. Please use the 'format' option for now.
13
21
 
14
22
  config_name "faye"
15
23
 
@@ -19,90 +27,139 @@ class LogStash::Outputs::Faye < LogStash::Outputs::Base
19
27
  # Faye-security-token
20
28
  config :faye_token, :validate => :string
21
29
 
22
- # Url of the faye-server
30
+ # URL to use
23
31
  config :url, :validate => :string, :default => "http://localhost:9292/faye"
24
32
 
25
- # If TLS/SSL is used (because the `url` is "https://...", then this
26
- # setting will determine if certificate validation is done.
27
- #
28
- # Note: If you set this to false, you will be destroying the security
29
- # features provided by TLS. Setting this to false is never recommended,
30
- # especially never in production.
31
- config :verify_ssl, :validate => :boolean, :default => true
32
-
33
33
  # This lets you choose the structure and parts of the event that are sent.
34
34
  #
35
- # For example:
36
35
  #
37
- # mapping => ["foo", "%{host}", "bar", "%{type}"]
36
+ # For example:
37
+ # [source,ruby]
38
+ # mapping => {"foo" => "%{host}"
39
+ # "bar" => "%{type}"}
38
40
  config :mapping, :validate => :hash
39
41
 
40
- public
41
42
  def register
42
- require "net/http"
43
- end # def register
43
+ @http_method = :post
44
+ @content_type = "application/json"
44
45
 
45
- public
46
- def receive(event)
47
- return unless output?(event)
46
+ # We count outstanding requests with this queue
47
+ # This queue tracks the requests to create backpressure
48
+ # When this queue is empty no new requests may be sent,
49
+ # tokens must be added back by the client on success
50
+ @request_tokens = SizedQueue.new(@pool_max)
51
+ @pool_max.times {|t| @request_tokens << true }
48
52
 
49
- _send_message event
50
- end # def receive
53
+ @requests = Array.new
54
+ end # def register
51
55
 
52
- private
53
- def _send_message(event)
56
+ def multi_receive(events)
57
+ events.each {|event| receive(event, :parallel)}
58
+ client.execute!
59
+ end
54
60
 
55
- if @mapping
56
- message = Hash.new
57
- @mapping.each do |k,v|
58
- message[k] = event.sprintf(v)
59
- end
60
- else
61
- message = event.to_hash
62
- end
61
+ # Once we no longer need to support Logstash < 2.2 (pre-ng-pipeline)
62
+ # We don't need to handle :background style requests
63
+ #
64
+ # We use :background style requests for Logstash < 2.2 because before the microbatching
65
+ # pipeline performance is greatly improved by having some degree of async behavior.
66
+ #
67
+ # In Logstash 2.2 and after things are much simpler, we just run each batch in parallel
68
+ # This will make performance much easier to reason about, and more importantly let us guarantee
69
+ # that if `multi_receive` returns all items have been sent.
70
+ def receive(event, async_type=:background)
63
71
 
64
72
  if @faye_token
65
- message = {:channel => @channel, :data => message, :ext => {:auth_token => @faye_token}}
73
+ body = LogStash::Json.dump({:channel => @channel, :data => map_event(event), :ext => {:auth_token => @faye_token}})
66
74
  else
67
- message = {:channel => @channel, :data => message}
75
+ body = LogStash::Json.dump({:channel => @channel, :data => map_event(event)})
68
76
  end
69
77
 
70
- uri = URI.parse(@url)
78
+ # Block waiting for a token
79
+ token = @request_tokens.pop if async_type == :background
80
+
81
+ # Send the request
82
+ url = event.sprintf(@url)
83
+ headers = event_headers(event)
71
84
 
72
- begin
73
- http = Net::HTTP.new(uri.host, uri.port)
85
+ # Create an async request
86
+ request = client.send(async_type).send(@http_method, url, :body => body, :headers => headers)
74
87
 
75
- if uri.scheme == 'https'
76
- http.use_ssl = true
88
+ request.on_complete do
89
+ # Make sure we return the token to the pool
90
+ @request_tokens << token if async_type == :background
91
+ end
77
92
 
78
- if !@verify_ssl
79
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
80
- else
81
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
82
- end
93
+ request.on_success do |response|
94
+ if response.code < 200 || response.code > 299
95
+ log_failure(
96
+ "Encountered non-200 HTTP code #{response.code}",
97
+ :response_code => response.code,
98
+ :url => url,
99
+ :event => event.to_hash)
83
100
  end
101
+ end
102
+
103
+ request.on_failure do |exception|
104
+ log_failure("Could not fetch URL",
105
+ :url => url,
106
+ :method => @http_method,
107
+ :body => faye_body.to_json,
108
+ :headers => headers,
109
+ :message => exception.message,
110
+ :class => exception.class.name,
111
+ :backtrace => exception.backtrace
112
+ )
113
+ end
114
+
115
+ request.call if async_type == :background
116
+ end
117
+
118
+ def close
119
+ client.close
120
+ end
84
121
 
85
- request = Net::HTTP::Post.new(uri.path)
86
- request.set_form_data(:message => message.to_json)
122
+ private
87
123
 
88
- response = http.request(request)
124
+ # This is split into a separate method mostly to help testing
125
+ def log_failure(message, opts)
126
+ @logger.error("[HTTP Output Failure] #{message}", opts)
127
+ end
89
128
 
90
- if response.is_a?(Net::HTTPSuccess)
91
- message = JSON.parse(response.body)
129
+ # Manticore doesn't provide a way to attach handlers to background or async requests well
130
+ # It wants you to use futures. The #async method kinda works but expects single thread batches
131
+ # and background only returns futures.
132
+ # Proposed fix to manticore here: https://github.com/cheald/manticore/issues/32
133
+ def request_async_background(request)
134
+ @method ||= client.executor.java_method(:submit, [java.util.concurrent.Callable.java_class])
135
+ @method.call(request)
136
+ end
92
137
 
93
- @logger.warn("Faye request was not successfully", message.first) unless message.first['successful']
94
- else
95
- @logger.warn("Faye response not ok", :http_status => response.code, :message => response.message)
138
+ def map_event(event)
139
+ if @mapping
140
+ @mapping.reduce({}) do |acc,kv|
141
+ k,v = kv
142
+ acc[k] = event.sprintf(v)
143
+ acc
96
144
  end
97
- rescue Exception => e
98
- @logger.warn("Unhandled exception", :request => request, :response => response, :exception => e, :stacktrace => e.backtrace)
145
+ else
146
+ event.to_hash
99
147
  end
100
-
101
148
  end
102
149
 
103
- def teardown
104
- finished
150
+ def event_headers(event)
151
+ headers = custom_headers(event) || {}
152
+ headers["Content-Type"] = @content_type
153
+ headers
105
154
  end
106
- end # class LogStash::Outputs::Faye
107
155
 
156
+ def custom_headers(event)
157
+ return nil unless @headers
108
158
 
159
+ @headers.reduce({}) do |acc,kv|
160
+ k,v = kv
161
+ acc[k] = event.sprintf(v)
162
+ acc
163
+ end
164
+ end
165
+ end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-output-faye'
4
- s.version = '2.2.0'
4
+ s.version = '3.0.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Send event to faye-message-server"
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/plugin install gemname. This gem is not a stand-alone program"
@@ -21,7 +21,10 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.20", "<= 2.99"
24
+ s.add_runtime_dependency "logstash-mixin-http_client", ">= 2.2.1", "< 5.0.0"
24
25
 
25
26
  s.add_development_dependency 'logstash-devutils'
27
+ s.add_development_dependency 'sinatra'
28
+ s.add_development_dependency 'webrick'
26
29
  end
27
30
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-faye
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Signify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-10 00:00:00.000000000 Z
11
+ date: 2016-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -30,6 +30,26 @@ dependencies:
30
30
  - - <=
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: 2.2.1
39
+ - - <
40
+ - !ruby/object:Gem::Version
41
+ version: 5.0.0
42
+ name: logstash-mixin-http_client
43
+ prerelease: false
44
+ type: :runtime
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: 2.2.1
50
+ - - <
51
+ - !ruby/object:Gem::Version
52
+ version: 5.0.0
33
53
  - !ruby/object:Gem::Dependency
34
54
  requirement: !ruby/object:Gem::Requirement
35
55
  requirements:
@@ -44,6 +64,34 @@ dependencies:
44
64
  - - '>='
45
65
  - !ruby/object:Gem::Version
46
66
  version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ name: sinatra
74
+ prerelease: false
75
+ type: :development
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ name: webrick
88
+ prerelease: false
89
+ type: :development
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
47
95
  description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
48
96
  email: dietmar@signifydata.com
49
97
  executables: []