logstash-output-json_batch 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee4f16aca346581c664061bb54a8277e221e5202
4
+ data.tar.gz: 12cba94b51e576e5f255b2cb3b6bd7aa80784325
5
+ SHA512:
6
+ metadata.gz: 4558c603e114ef0b404ff6e92074aede6a0c646a713f78890f5e65b9cc8df533a51dd9fdcb10a0184dfeb3ed112a5ccd6119ca7334b70984befbfd0a0fb78455
7
+ data.tar.gz: 3a6771048a1366e45acc1c252f4ca6cb66481539d1c75ce6fa2c468e771623dada1abd2deac0ba354ca52101c4ee3a6f22f40b71c6e7bde6cd53d83eb45dac6d
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2016 Lucidworks
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,26 @@
1
+ # Logstash Plugin
2
+
3
+ This plugin is a heavily butchered and modified version of the standard logstash http output plugin. That plugin is available [here](https://github.com/logstash-plugins/logstash-output-http).
4
+
5
+ It has been modified to only support JSON, but also supports batching of messages into JSON lists.
6
+
7
+ # Usage
8
+
9
+ Please note that the name of the plugin when used is `json_batch`, since it only supports json in its current form. If further output formats are added in the future, this might change back to http_batch.
10
+
11
+ output {
12
+ json_batch {
13
+ headers => ["Authorization", "Basic YWRtaW46cGFzc3dvcmQxMjM="]
14
+ url => "http://your.site/your/json/update/endpoint"
15
+ }
16
+ }
17
+
18
+ Default batch size is 50, with a wait of at most 5 seconds per send. These can be tweaked with the parameters `flush_size` and `idle_flush_time` respectively.
19
+
20
+ # Installation & build
21
+
22
+ To build the gem yourself, use `gem build logstash-output-json_batch.gemspec` in the root of this repository. Alternatively, you can download a built version of the gem from the `dist` branch of this repository.
23
+
24
+ To install, run the following command, assuming the gem is in the local directory: `$LOGSTASH_HOME/bin/plugin install logstash-output-json_batch-X.Y.Z.gem`
25
+
26
+ Direct links to the built versions of the gems are available on the [releases page](https://github.com/jwestberg/logstash-output-http_batch/releases)
@@ -0,0 +1,158 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/base"
3
+ require "logstash/namespace"
4
+ require "logstash/json"
5
+ require "uri"
6
+ require "stud/buffer"
7
+ require "logstash/plugin_mixins/http_client"
8
+
9
+ class LogStash::Outputs::JSONBatch < LogStash::Outputs::Base
10
+ include LogStash::PluginMixins::HttpClient
11
+ include Stud::Buffer
12
+
13
+ config_name "json_batch"
14
+
15
+ # URL to use
16
+ config :url, :validate => :string, :required => true
17
+
18
+ # Custom headers to use
19
+ # format is `headers => ["X-My-Header", "%{host}"]`
20
+ config :headers, :validate => :hash
21
+
22
+ config :flush_size, :validate => :number, :default => 50
23
+
24
+ config :idle_flush_time, :validate => :number, :default => 5
25
+
26
+ config :retry_individual, :validate => :boolean, :default => true
27
+
28
+ config :pool_max, :validate => :number, :default => 50
29
+
30
+ def register
31
+ # Handle this deprecated option. TODO: remove the option
32
+ #@ssl_certificate_validation = @verify_ssl if @verify_ssl
33
+
34
+ # We count outstanding requests with this queue
35
+ # This queue tracks the requests to create backpressure
36
+ # When this queue is empty no new requests may be sent,
37
+ # tokens must be added back by the client on success
38
+ @request_tokens = SizedQueue.new(@pool_max)
39
+ @pool_max.times {|t| @request_tokens << true }
40
+ @total = 0
41
+ @total_failed = 0
42
+ @requests = Array.new
43
+
44
+ buffer_initialize(
45
+ :max_items => @flush_size,
46
+ :max_interval => @idle_flush_time,
47
+ :logger => @logger
48
+ )
49
+ logger.info("Initialized json_batch with settings",
50
+ :flush_size => @flush_size,
51
+ :idle_flush_time => @idle_flush_time,
52
+ :request_tokens => @pool_max,
53
+ :url => @url,
54
+ :headers => request_headers,
55
+ :retry_individual => @retry_individual)
56
+
57
+ end # def register
58
+
59
+ # This module currently does not support parallel requests as that would circumvent the batching
60
+ def receive(event, async_type=:background)
61
+ buffer_receive(event)
62
+ end #def event
63
+
64
+ public
65
+ def flush(events, close=false)
66
+ documents = [] #this is the array of hashes that we push to Fusion as documents
67
+
68
+ events.each do |event|
69
+ document = event.to_hash()
70
+ documents.push(document)
71
+ end
72
+
73
+ make_request(documents)
74
+ end
75
+
76
+ def multi_receive(events)
77
+ events.each {|event| buffer_receive(event)}
78
+ end
79
+
80
+ private
81
+
82
+ def make_request(documents)
83
+ body = LogStash::Json.dump(documents)
84
+ # Block waiting for a token
85
+ #@logger.info("Requesting token ", :tokens => request_tokens.length())
86
+ token = @request_tokens.pop
87
+ @logger.debug("Got token", :tokens => @request_tokens.length)
88
+
89
+ # Create an async request
90
+ begin
91
+ request = client.send(:post, @url, :body => body, :headers => request_headers, :async => true)
92
+ rescue Exception => e
93
+ @logger.warn("An error occurred while indexing: #{e.message}")
94
+ end
95
+
96
+ # attach handlers before performing request
97
+ request.on_complete do
98
+ # Make sure we return the token to the pool
99
+ @request_tokens << token
100
+ end
101
+
102
+ request.on_success do |response|
103
+ if response.code >= 200 && response.code < 300
104
+ @total = @total + documents.length
105
+ @logger.debug("Successfully submitted",
106
+ :docs => documents.length,
107
+ :response_code => response.code,
108
+ :total => @total)
109
+ else
110
+ if documents.length > 1 && @retry_individual
111
+ documents.each do |doc|
112
+ make_request([doc])
113
+ end
114
+ else
115
+ @total_failed += documents.length
116
+ log_failure(
117
+ "Encountered non-200 HTTP code #{response.code}",
118
+ :response_code => response.code,
119
+ :url => url,
120
+ :response_body => response.body,
121
+ :num_docs => documents.length,
122
+ :retry_individual => @retry_individual,
123
+ :total_failed => @total_failed)
124
+ end
125
+ end
126
+ end
127
+
128
+ request.on_failure do |exception|
129
+ @total_failed += documents.length
130
+ log_failure("Could not access URL",
131
+ :url => url,
132
+ :method => @http_method,
133
+ :body => body,
134
+ :headers => headers,
135
+ :message => exception.message,
136
+ :class => exception.class.name,
137
+ :backtrace => exception.backtrace,
138
+ :total_failed => @total_failed
139
+ )
140
+ end
141
+
142
+ Thread.new do
143
+ client.execute!
144
+ end
145
+ end
146
+
147
+ # This is split into a separate method mostly to help testing
148
+ def log_failure(message, opts)
149
+ @logger.error("[HTTP Output Failure] #{message}", opts)
150
+ end
151
+
152
+ def request_headers()
153
+ headers = @headers || {}
154
+ headers["Content-Type"] ||= "application/json"
155
+ headers
156
+ end
157
+
158
+ end
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-output-json_batch'
3
+ s.version = '0.2.0'
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = "This output lets you `POST` messages as JSON in a batched fashion to a HTTP endpoint"
6
+ 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"
7
+ s.authors = ["jwestberg"]
8
+ s.email = 'joel.westberg@lucidworks.com'
9
+ s.homepage = "http://lucidworks.com"
10
+ s.require_paths = ["lib"]
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','*.gemspec','*.md','Gemfile','LICENSE' ]
14
+
15
+ # Tests
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+
18
+ # Special flag to let us know this is actually a logstash plugin
19
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
20
+
21
+ # Gem dependencies
22
+ s.add_runtime_dependency "logstash-core-plugin-api", "~> 1.0"
23
+ s.add_runtime_dependency "logstash-mixin-http_client", ">= 2.2.1", "< 3.0.0"
24
+
25
+ s.add_development_dependency 'logstash-devutils'
26
+ s.add_development_dependency 'sinatra'
27
+ s.add_development_dependency 'webrick'
28
+ end
29
+
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-output-json_batch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - jwestberg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ name: logstash-core-plugin-api
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.2.1
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: 3.0.0
36
+ name: logstash-mixin-http_client
37
+ prerelease: false
38
+ type: :runtime
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.2.1
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.0
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ name: logstash-devutils
54
+ prerelease: false
55
+ type: :development
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ name: sinatra
68
+ prerelease: false
69
+ type: :development
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
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'
89
+ 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
90
+ email: joel.westberg@lucidworks.com
91
+ executables: []
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - Gemfile
96
+ - LICENSE
97
+ - README.md
98
+ - lib/logstash/outputs/json_batch.rb
99
+ - logstash-output-json_batch.gemspec
100
+ homepage: http://lucidworks.com
101
+ licenses:
102
+ - Apache License (2.0)
103
+ metadata:
104
+ logstash_plugin: 'true'
105
+ logstash_group: output
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.4.8
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: This output lets you `POST` messages as JSON in a batched fashion to a HTTP endpoint
126
+ test_files: []