logstash-output-edge_http 1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a076945788c4f08facd2cb2e61717e26e77431552c7ac846ce4bf8401fb156d4
4
+ data.tar.gz: 0cb3ebf49320c940bfb4ad29f65af21c59c12227b97de1f06391c4b3e2eddea8
5
+ SHA512:
6
+ metadata.gz: 22d7e935ba950ae5a401524867efefa8f58803f99151af98ae82e439eefc1e45c901bfe0c1245a25a5c90932f16673fd1fb82a92e50f70e1b085614f951fe3d3
7
+ data.tar.gz: ac400ffed57010d459a6adcdde926a1ae379296c94c03cd77f0148fd0baa9b7f6783983451af7ab54517aab5cd6ba1467384de3f029c0a65f34e9ad2e9a32ed8
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ logstash_path = ENV["LOGSTASH_PATH"] || "./logstash"
6
+
7
+ if Dir.exist?(logstash_path)
8
+ gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
9
+ gem 'logstash-mixin-http_client', :path => "#{logstash_path}/vendor/bundle/jruby/2.6.0/gems/logstash-mixin-http_client"
10
+ else
11
+ raise 'missing logstash vendoring'
12
+ end
13
+
14
+ gem "oauth2", "~> 2.0.9"
15
+ gem "webmock", "~> 3.8"
16
+ gem 'logstash-devutils', "~> 2"
17
+ gem 'sinatra'
18
+ gem 'webrick'
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Contributing to Loki Logstash Output Plugin
2
+
3
+ For information about how to use this plugin see this [documentation](../../docs/sources/clients/logstash/_index.md).
4
+
5
+ ## Install dependencies
6
+
7
+ First, make sure you have JDK version `8` or `11` installed and you have set the `JAVA_HOME` environment variable.
8
+
9
+ You need to setup JRuby environment to build this plugin. Refer https://github.com/rbenv/rbenv for setting up your rbenv environment.
10
+
11
+ After setting up `rbenv`. Install JRuby
12
+
13
+ ```bash
14
+ rbenv install jruby-9.2.10.0
15
+ rbenv local jruby-9.2.10.0
16
+ ```
17
+
18
+ Check that the environment is configured
19
+
20
+ ```bash
21
+ ruby --version
22
+ jruby 9.2.10
23
+ ```
24
+
25
+ You should make sure you are running `jruby` and not `ruby`. If the command `ruby --version` still shows `ruby` and not `jruby`, check that PATH contains `$HOME/.rbenv/shims` and `$HOME/.rbenv/bin`. Also verify that you have this in your bash profile:
26
+
27
+ ```bash
28
+ export PATH="$HOME/.rbenv/bin:$PATH"
29
+ eval "$(rbenv init -)"
30
+ ```
31
+
32
+ Then install bundler:
33
+
34
+ ```bash
35
+ gem install bundler:2.1.4
36
+ ```
37
+
38
+ Follow those instructions to [install logstash](https://www.elastic.co/guide/en/logstash/current/installing-logstash.html) before moving to the next section.
39
+
40
+ ## Build and test the plugin
41
+
42
+ ### Install required packages
43
+
44
+ ```bash
45
+ git clone git@github.com:elastic/logstash.git
46
+ cd logstash
47
+ git checkout tags/v7.16.1
48
+ export LOGSTASH_PATH="$(pwd)"
49
+ export GEM_PATH="$LOGSTASH_PATH/vendor/bundle/jruby/2.5.0"
50
+ export GEM_HOME="$LOGSTASH_PATH/vendor/bundle/jruby/2.5.0"
51
+ ./gradlew assemble
52
+ cd ..
53
+ ruby -S bundle /config set --local path "$LOGSTASH_PATH/vendor/bundle"
54
+ ruby -S bundle install
55
+ ruby -S bundle exec rake vendor
56
+ ```
57
+
58
+ ### Build the plugin
59
+
60
+ ```bash
61
+ gem build logstash-output-loki.gemspec
62
+ ```
63
+
64
+ ### Test
65
+
66
+ ```bash
67
+ ruby -S bundle exec rspec
68
+ ```
69
+
70
+ Alternatively if you don't want to install JRuby. Enter inside logstash-loki container.
71
+
72
+ ```bash
73
+ docker build -t logstash-loki ./
74
+ docker run -v $(pwd)/spec:/home/logstash/spec -it --rm --entrypoint /bin/sh logstash-loki
75
+ bundle exec rspec
76
+ ```
77
+
78
+ ## Install plugin to local logstash
79
+
80
+ ```bash
81
+ bin/logstash-plugin install --no-verify --local logstash-output-loki-1.0.0.gem
82
+ ```
83
+
84
+ ## Send sample event and check plugin is working
85
+
86
+ ```bash
87
+ bin/logstash -f loki.conf
88
+ ```
@@ -0,0 +1,414 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/base"
3
+ require "logstash/namespace"
4
+ require "logstash/json"
5
+ require "uri"
6
+ require "logstash/plugin_mixins/http_client"
7
+ require "zlib"
8
+ require 'oauth2'
9
+
10
+ class LogStash::Outputs::Http < LogStash::Outputs::Base
11
+ include LogStash::PluginMixins::HttpClient
12
+
13
+ concurrency :shared
14
+
15
+ attr_accessor :is_batch
16
+
17
+ VALID_METHODS = ["put", "post", "patch", "delete", "get", "head"]
18
+
19
+ RETRYABLE_MANTICORE_EXCEPTIONS = [
20
+ ::Manticore::Timeout,
21
+ ::Manticore::SocketException,
22
+ ::Manticore::ClientProtocolException,
23
+ ::Manticore::ResolutionFailure,
24
+ ::Manticore::SocketTimeout
25
+ ]
26
+
27
+ RETRYABLE_UNKNOWN_EXCEPTION_STRINGS = [
28
+ /Connection reset by peer/i,
29
+ /Read Timed out/i
30
+ ]
31
+
32
+ class PluginInternalQueueLeftoverError < StandardError; end
33
+
34
+ # This output lets you send events to a
35
+ # generic HTTP(S) endpoint
36
+ #
37
+ # This output will execute up to 'pool_max' requests in parallel for performance.
38
+ # Consider this when tuning this plugin for performance.
39
+ #
40
+ # Additionally, note that when parallel execution is used strict ordering of events is not
41
+ # guaranteed!
42
+ #
43
+ # Beware, this gem does not yet support codecs. Please use the 'format' option for now.
44
+
45
+ config_name "http"
46
+
47
+ # URL to use
48
+ config :url, :validate => :string, :required => :true
49
+
50
+ # The HTTP Verb. One of "put", "post", "patch", "delete", "get", "head"
51
+ config :http_method, :validate => VALID_METHODS, :required => :true
52
+
53
+ # Custom headers to use
54
+ # format is `headers => ["X-My-Header", "%{host}"]`
55
+ config :headers, :validate => :hash, :default => {}
56
+
57
+ # Content type
58
+ #
59
+ # If not specified, this defaults to the following:
60
+ #
61
+ # * if format is "json", "application/json"
62
+ # * if format is "form", "application/x-www-form-urlencoded"
63
+ config :content_type, :validate => :string
64
+
65
+ # Set this to false if you don't want this output to retry failed requests
66
+ config :retry_failed, :validate => :boolean, :default => true
67
+
68
+ # If encountered as response codes this plugin will retry these requests
69
+ config :retryable_codes, :validate => :number, :list => true, :default => [429, 500, 502, 503, 504]
70
+
71
+ # If you would like to consider some non-2xx codes to be successes
72
+ # enumerate them here. Responses returning these codes will be considered successes
73
+ config :ignorable_codes, :validate => :number, :list => true
74
+
75
+ # This lets you choose the structure and parts of the event that are sent.
76
+ #
77
+ #
78
+ # For example:
79
+ # [source,ruby]
80
+ # mapping => {"foo" => "%{host}"
81
+ # "bar" => "%{type}"}
82
+ config :mapping, :validate => :hash
83
+
84
+ # Set the format of the http body.
85
+ #
86
+ # If form, then the body will be the mapping (or whole event) converted
87
+ # into a query parameter string, e.g. `foo=bar&baz=fizz...`
88
+ #
89
+ # If message, then the body will be the result of formatting the event according to message
90
+ #
91
+ # Otherwise, the event is sent as json.
92
+ config :format, :validate => ["json", "json_batch", "form", "message"], :default => "json"
93
+
94
+ # Set this to true if you want to enable gzip compression for your http requests
95
+ config :http_compression, :validate => :boolean, :default => false
96
+
97
+ config :message, :validate => :string
98
+
99
+ def register
100
+ @http_method = @http_method.to_sym
101
+
102
+ # We count outstanding requests with this queue
103
+ # This queue tracks the requests to create backpressure
104
+ # When this queue is empty no new requests may be sent,
105
+ # tokens must be added back by the client on success
106
+ @request_tokens = SizedQueue.new(@pool_max)
107
+ @pool_max.times {|t| @request_tokens << true }
108
+
109
+ @requests = Array.new
110
+
111
+ if @content_type.nil?
112
+ case @format
113
+ when "form" ; @content_type = "application/x-www-form-urlencoded"
114
+ when "json" ; @content_type = "application/json"
115
+ when "json_batch" ; @content_type = "application/json"
116
+ when "message" ; @content_type = "text/plain"
117
+ end
118
+ end
119
+
120
+ @is_batch = @format == "json_batch"
121
+
122
+ @headers["Content-Type"] = @content_type
123
+
124
+ validate_format!
125
+
126
+ # Run named Timer as daemon thread
127
+ @timer = java.util.Timer.new("HTTP Output #{self.params['id']}", true)
128
+ end # def register
129
+
130
+ def multi_receive(events)
131
+ return if events.empty?
132
+ send_events(events)
133
+ end
134
+
135
+ class RetryTimerTask < java.util.TimerTask
136
+ def initialize(pending, event, attempt)
137
+ @pending = pending
138
+ @event = event
139
+ @attempt = attempt
140
+ super()
141
+ end
142
+
143
+ def run
144
+ @pending << [@event, @attempt]
145
+ end
146
+ end
147
+
148
+ def log_retryable_response(response)
149
+ retry_msg = @retry_failed ? 'will retry' : "won't retry"
150
+ if (response.code == 429)
151
+ @logger.debug? && @logger.debug("Encountered a 429 response, #{retry_msg}. This is not serious, just flow control via HTTP")
152
+ else
153
+ @logger.warn("Encountered a retryable HTTP request in HTTP output, #{retry_msg}", :code => response.code, :body => response.body)
154
+ end
155
+ end
156
+
157
+ def log_error_response(response, url, event)
158
+ log_failure(
159
+ "Encountered non-2xx HTTP code #{response.code}",
160
+ :response_code => response.code,
161
+ :url => url,
162
+ :event => event
163
+ )
164
+ end
165
+
166
+ def send_events(events)
167
+ successes = java.util.concurrent.atomic.AtomicInteger.new(0)
168
+ failures = java.util.concurrent.atomic.AtomicInteger.new(0)
169
+ retries = java.util.concurrent.atomic.AtomicInteger.new(0)
170
+ event_count = @is_batch ? 1 : events.size
171
+
172
+ pending = Queue.new
173
+ if @is_batch
174
+ pending << [events, 0]
175
+ else
176
+ events.each {|e| pending << [e, 0]}
177
+ end
178
+
179
+ while popped = pending.pop
180
+ break if popped == :done
181
+
182
+ event, attempt = popped
183
+
184
+ raise PluginInternalQueueLeftoverError.new("Received pipeline shutdown request but http output has unfinished events. " \
185
+ "If persistent queue is enabled, events will be retried.") if attempt > 2 && pipeline_shutdown_requested?
186
+
187
+ action, event, attempt = send_event(event, attempt)
188
+ begin
189
+ action = :failure if action == :retry && !@retry_failed
190
+
191
+ case action
192
+ when :success
193
+ successes.incrementAndGet
194
+ when :retry
195
+ retries.incrementAndGet
196
+
197
+ next_attempt = attempt+1
198
+ sleep_for = sleep_for_attempt(next_attempt)
199
+ @logger.info("Retrying http request, will sleep for #{sleep_for} seconds")
200
+ timer_task = RetryTimerTask.new(pending, event, next_attempt)
201
+ @timer.schedule(timer_task, sleep_for*1000)
202
+ when :failure
203
+ failures.incrementAndGet
204
+ else
205
+ raise "Unknown action #{action}"
206
+ end
207
+
208
+ if action == :success || action == :failure
209
+ if successes.get+failures.get == event_count
210
+ pending << :done
211
+ end
212
+ end
213
+ rescue => e
214
+ # This should never happen unless there's a flat out bug in the code
215
+ @logger.error("Error sending HTTP Request",
216
+ :class => e.class.name,
217
+ :message => e.message,
218
+ :backtrace => e.backtrace)
219
+ failures.incrementAndGet
220
+ raise e
221
+ end
222
+ end
223
+ rescue => e
224
+ @logger.error("Error in http output loop",
225
+ :class => e.class.name,
226
+ :message => e.message,
227
+ :backtrace => e.backtrace)
228
+ raise e
229
+ end
230
+
231
+ def pipeline_shutdown_requested?
232
+ return super if defined?(super) # since LS 8.1.0
233
+ nil
234
+ end
235
+
236
+ def sleep_for_attempt(attempt)
237
+ sleep_for = attempt**2
238
+ sleep_for = sleep_for <= 60 ? sleep_for : 60
239
+ (sleep_for/2) + (rand(0..sleep_for)/2)
240
+ end
241
+
242
+ def send_event(event, attempt)
243
+ body = event_body(event)
244
+
245
+ # Send the request
246
+ url = @is_batch ? @url : event.sprintf(@url)
247
+ headers = @is_batch ? @headers : event_headers(event)
248
+
249
+ # Compress the body and add appropriate header
250
+ if @http_compression == true
251
+ headers["Content-Encoding"] = "gzip"
252
+ body = gzip(body)
253
+ end
254
+
255
+ # Create an async request
256
+ response = client.send(@http_method, url, :body => body, :headers => headers).call
257
+
258
+ if !response_success?(response)
259
+ if retryable_response?(response)
260
+ log_retryable_response(response)
261
+ return :retry, event, attempt
262
+ else
263
+ log_error_response(response, url, event)
264
+ return :failure, event, attempt
265
+ end
266
+ else
267
+ return :success, event, attempt
268
+ end
269
+
270
+ rescue => exception
271
+ will_retry = retryable_exception?(exception)
272
+ log_params = {
273
+ :url => url,
274
+ :method => @http_method,
275
+ :message => exception.message,
276
+ :class => exception.class,
277
+ :will_retry => will_retry
278
+ }
279
+ if @logger.debug?
280
+ # backtraces are big
281
+ log_params[:backtrace] = exception.backtrace
282
+ # headers can have sensitive data
283
+ log_params[:headers] = headers
284
+ # body can be big and may have sensitive data
285
+ log_params[:body] = body
286
+ end
287
+ log_failure("Could not fetch URL", log_params)
288
+
289
+ if will_retry
290
+ return :retry, event, attempt
291
+ else
292
+ return :failure, event, attempt
293
+ end
294
+ end
295
+
296
+ def close
297
+ @timer.cancel
298
+ client.close
299
+ end
300
+
301
+ private
302
+
303
+ def response_success?(response)
304
+ code = response.code
305
+ return true if @ignorable_codes && @ignorable_codes.include?(code)
306
+ return code >= 200 && code <= 299
307
+ end
308
+
309
+ def retryable_response?(response)
310
+ @retryable_codes && @retryable_codes.include?(response.code)
311
+ end
312
+
313
+ def retryable_exception?(exception)
314
+ retryable_manticore_exception?(exception) || retryable_unknown_exception?(exception)
315
+ end
316
+
317
+ def retryable_manticore_exception?(exception)
318
+ RETRYABLE_MANTICORE_EXCEPTIONS.any? {|me| exception.is_a?(me)}
319
+ end
320
+
321
+ def retryable_unknown_exception?(exception)
322
+ exception.is_a?(::Manticore::UnknownException) &&
323
+ RETRYABLE_UNKNOWN_EXCEPTION_STRINGS.any? { |snippet| exception.message =~ snippet }
324
+ end
325
+
326
+ # This is split into a separate method mostly to help testing
327
+ def log_failure(message, opts)
328
+ @logger.error(message, opts)
329
+ end
330
+
331
+ # Format the HTTP body
332
+ def event_body(event)
333
+ # TODO: Create an HTTP post data codec, use that here
334
+ if @format == "json"
335
+ LogStash::Json.dump(map_event(event))
336
+ elsif @format == "message"
337
+ event.sprintf(@message)
338
+ elsif @format == "json_batch"
339
+ LogStash::Json.dump(event.map {|e| map_event(e) })
340
+ else
341
+ encode(map_event(event))
342
+ end
343
+ end
344
+
345
+ # gzip data
346
+ def gzip(data)
347
+ gz = StringIO.new
348
+ gz.set_encoding("BINARY")
349
+ z = Zlib::GzipWriter.new(gz)
350
+ z.write(data)
351
+ z.close
352
+ gz.string
353
+ end
354
+
355
+ def convert_mapping(mapping, event)
356
+ if mapping.is_a?(Hash)
357
+ mapping.reduce({}) do |acc, kv|
358
+ k, v = kv
359
+ acc[k] = convert_mapping(v, event)
360
+ acc
361
+ end
362
+ elsif mapping.is_a?(Array)
363
+ mapping.map { |elem| convert_mapping(elem, event) }
364
+ else
365
+ event.sprintf(mapping)
366
+ end
367
+ end
368
+
369
+ def map_event(event)
370
+ if @mapping
371
+ convert_mapping(@mapping, event)
372
+ else
373
+ event.to_hash
374
+ end
375
+ end
376
+
377
+ def event_headers(event)
378
+ custom_headers(event) || {}
379
+ end
380
+
381
+ def custom_headers(event)
382
+ return nil unless @headers
383
+
384
+ @headers.reduce({}) do |acc,kv|
385
+ k,v = kv
386
+ acc[k] = event.sprintf(v)
387
+ acc
388
+ end
389
+ end
390
+
391
+ #TODO Extract this to a codec
392
+ def encode(hash)
393
+ return hash.collect do |key, value|
394
+ CGI.escape(key) + "=" + CGI.escape(value.to_s)
395
+ end.join("&")
396
+ end
397
+
398
+
399
+ def validate_format!
400
+ if @format == "message"
401
+ if @message.nil?
402
+ raise "message must be set if message format is used"
403
+ end
404
+
405
+ if @content_type.nil?
406
+ raise "content_type must be set if message format is used"
407
+ end
408
+
409
+ unless @mapping.nil?
410
+ @logger.warn "mapping is not supported and will be ignored if message format is used"
411
+ end
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,32 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-output-edge_http'
3
+ s.version = '1.0.0'
4
+ s.authors = ['Britto Prabhu']
5
+ s.email = ['britto.prabhu@apmterminals.com']
6
+
7
+ s.summary = 'Output plugin to ship logs to Loki server with oauth2 token'
8
+ s.description = 'This Output plugin to ship logs to Loki server with oauth2 token and proxy support'
9
+ s.summary = "Sends events to a generic HTTP or HTTPS endpoint with additional oauth2 token support"
10
+ 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. This plugin supports oauth2 token."
11
+ s.homepage = 'https://github.com/Maersk-Global/apmt-observability-deployment'
12
+ s.license = 'Apache-2.0'
13
+ s.require_paths = ["lib"]
14
+
15
+ # Files
16
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
17
+
18
+ # Tests
19
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
+
21
+ # Special flag to let us know this is actually a logstash plugin
22
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
23
+
24
+ # Gem dependencies
25
+ s.add_runtime_dependency "oauth2", "~> 2.0.9"
26
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
27
+ s.add_runtime_dependency "logstash-mixin-http_client", ">= 7.2.0", "< 8.0.0"
28
+
29
+ s.add_development_dependency 'logstash-devutils'
30
+ s.add_development_dependency 'sinatra'
31
+ s.add_development_dependency 'webrick'
32
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-output-edge_http
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Britto Prabhu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-09-09 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: 2.0.9
19
+ name: oauth2
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.9
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '1.60'
33
+ - - "<="
34
+ - !ruby/object:Gem::Version
35
+ version: '2.99'
36
+ name: logstash-core-plugin-api
37
+ prerelease: false
38
+ type: :runtime
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '1.60'
44
+ - - "<="
45
+ - !ruby/object:Gem::Version
46
+ version: '2.99'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 7.2.0
53
+ - - "<"
54
+ - !ruby/object:Gem::Version
55
+ version: 8.0.0
56
+ name: logstash-mixin-http_client
57
+ prerelease: false
58
+ type: :runtime
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 7.2.0
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: 8.0.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: logstash-devutils
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: sinatra
88
+ prerelease: false
89
+ type: :development
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ name: webrick
102
+ prerelease: false
103
+ type: :development
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ description: This gem is a Logstash plugin required to be installed on top of the
110
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
111
+ gem is not a stand-alone program. This plugin supports oauth2 token.
112
+ email:
113
+ - britto.prabhu@apmterminals.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - Gemfile
119
+ - README.md
120
+ - lib/logstash/outputs/edge_http.rb
121
+ - logstash-output-edge_http.gemspec
122
+ homepage: https://github.com/Maersk-Global/apmt-observability-deployment
123
+ licenses:
124
+ - Apache-2.0
125
+ metadata:
126
+ logstash_plugin: 'true'
127
+ logstash_group: output
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubygems_version: 3.2.33
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Sends events to a generic HTTP or HTTPS endpoint with additional oauth2 token
147
+ support
148
+ test_files: []