logstash-input-http_poller 3.0.3 → 3.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: 9a540e3224516716a40ccbad3b6c0006a689d0c8
4
- data.tar.gz: 6771a22df2b09883e6e853add0c86c669289108c
3
+ metadata.gz: fe8e760b955fa42eefe9e32efb1d22a45a5df599
4
+ data.tar.gz: 78892043c7636c6ae2390f0a0434049f2c0746a7
5
5
  SHA512:
6
- metadata.gz: ee59e72aee1dad65d3df850cf2eb9bbada57562c7207d1e0c3695b2a2f6e1d7a7a895061e86bc554e072e29d9da5060e0374633818e27dbcfc284c8b36f20551
7
- data.tar.gz: c46f4edcef1d326cdcf88c8b7ffddbd6b088244a76c4b09884f23ea13cee9201e7c523482ffc5555e9244b358440fea43def47b8c6ec9712e2af319db704018b
6
+ metadata.gz: 981963c7a77ca4ee065efea7dce6cfcef8764e58cca1c168275da196bf9f8255ec34af2ad52fc9051d019faf7820628fb41c37744ee492107f46e9f20f818ae8
7
+ data.tar.gz: f1db89d4d1a1a44dd750c0348e95b95875844af1a815efb4f9f8bb8e56084d45aa119cd433fb83f0ab775df8e54313783dac51d0997d7c8a6ec1a6f544362fb4
data/CHANGELOG.md CHANGED
@@ -1,15 +1,24 @@
1
+ ## 3.1.0
2
+ - Use rufus-scheduler for more flexible scheduling. Many thanks to [@hummingV](https://github.com/hummingV) for this contribution. ([#58](https://github.com/logstash-plugins/logstash-input-http_poller/pull/58))
3
+
1
4
  ## 3.0.3
2
5
  - Require logstash-mixin-http_client 4.0.3 which fixes error messaging around key/trust-stores when no password supplied
6
+
3
7
  ## 3.0.2
4
8
  - Relax constraint on logstash-core-plugin-api to >= 1.60 <= 2.99
9
+
5
10
  ## 3.0.1
6
11
  - Republish all the gems under jruby.
12
+
7
13
  ## 3.0.0
8
14
  - Update the plugin to the version 2.0 of the plugin api, this change is required for Logstash 5.0 compatibility. See https://github.com/elastic/logstash/issues/5141
9
- # 2.0.5
15
+
16
+ ## 2.0.5
10
17
  - Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
11
- # 2.0.4
18
+
19
+ ## 2.0.4
12
20
  - New dependency requirements for logstash-core for the 5.0 release
21
+
13
22
  ## 2.0.2
14
23
  - Bump http_client mixin to use better stale check for keepalives
15
24
 
@@ -4,6 +4,7 @@ require "logstash/namespace"
4
4
  require "logstash/plugin_mixins/http_client"
5
5
  require "socket" # for Socket.gethostname
6
6
  require "manticore"
7
+ require "rufus/scheduler"
7
8
 
8
9
  # This Logstash input plugin allows you to call an HTTP API, decode the output of it into event(s), and
9
10
  # send them on their merry way. The idea behind this plugins came from a need to read springboot
@@ -33,7 +34,8 @@ require "manticore"
33
34
  # }
34
35
  # }
35
36
  # request_timeout => 60
36
- # interval => 60
37
+ # # Supports "cron", "every", "at" and "in" schedules by rufus scheduler
38
+ # schedule => { cron => "* * * * * UTC"}
37
39
  # codec => "json"
38
40
  # # A hash of request metadata info (timing, response headers, etc.) will be sent here
39
41
  # metadata_target => "http_poller_metadata"
@@ -51,9 +53,10 @@ require "manticore"
51
53
  #
52
54
  # If you have a self signed cert you will need to convert your server's certificate to a valid# `.jks` or `.p12` file. An easy way to do it is to run the following one-liner, substituting your server's URL for the placeholder `MYURL` and `MYPORT`.
53
55
  #
54
- #....
56
+ # [source,ruby]
57
+ # ----------------------------------
55
58
  # openssl s_client -showcerts -connect MYURL:MYPORT </dev/null 2>/dev/null|openssl x509 -outform PEM > downloaded_cert.pem; keytool -import -alias test -file downloaded_cert.pem -keystore downloaded_truststore.jks
56
- #....
59
+ # ----------------------------------
57
60
  #
58
61
  # The above snippet will create two files `downloaded_cert.pem` and `downloaded_truststore.jks`. You will be prompted to set a password for the `jks` file during this process. To configure logstash use a config like the one that follows.
59
62
  #
@@ -70,9 +73,9 @@ require "manticore"
70
73
  # interval => 30
71
74
  # }
72
75
  #}
76
+ # ----------------------------------
73
77
  #
74
78
 
75
-
76
79
  class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
77
80
  include LogStash::PluginMixins::HttpClient
78
81
 
@@ -85,7 +88,20 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
85
88
  config :urls, :validate => :hash, :required => true
86
89
 
87
90
  # How often (in seconds) the urls will be called
88
- config :interval, :validate => :number, :required => true
91
+ # DEPRECATED. Use 'schedule' option instead.
92
+ # If both interval and schedule options are specified, interval
93
+ # option takes higher precedence
94
+ config :interval, :validate => :number, :deprecated => true
95
+
96
+ # Schedule of when to periodically poll from the urls
97
+ # Format: A hash with
98
+ # + key: "cron" | "every" | "in" | "at"
99
+ # + value: string
100
+ # Examples:
101
+ # a) { "every" => "1h" }
102
+ # b) { "cron" => "* * * * * UTC" }
103
+ # See: rufus/scheduler for details about different schedule options and value string format
104
+ config :schedule, :validate => :hash
89
105
 
90
106
  # Define the target field for placing the received data. If this setting is omitted, the data will be stored at the root (top level) of the event.
91
107
  config :target, :validate => :string
@@ -96,17 +112,19 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
96
112
  config :metadata_target, :validate => :string, :default => '@metadata'
97
113
 
98
114
  public
115
+ Schedule_types = %w(cron every at in)
99
116
  def register
100
117
  @host = Socket.gethostname.force_encoding(Encoding::UTF_8)
101
118
 
102
119
  @logger.info("Registering http_poller Input", :type => @type,
103
- :urls => @urls, :interval => @interval, :timeout => @timeout)
120
+ :urls => @urls, :interval => @interval, :schedule => @schedule, :timeout => @timeout)
104
121
 
105
122
  setup_requests!
106
123
  end
107
124
 
108
125
  def stop
109
126
  Stud.stop!(@interval_thread) if @interval_thread
127
+ @scheduler.stop if @scheduler
110
128
  end
111
129
 
112
130
  private
@@ -159,13 +177,46 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
159
177
 
160
178
  public
161
179
  def run(queue)
180
+ #interval or schedule must be provided. Must be exclusively either one. Not neither. Not both.
181
+ raise LogStash::ConfigurationError, "Invalid config. Neither interval nor schedule was specified." \
182
+ unless @interval || @schedule
183
+ raise LogStash::ConfigurationError, "Invalid config. Specify only interval or schedule. Not both." \
184
+ if @interval && @schedule
185
+
186
+ if @interval
187
+ setup_interval(queue)
188
+ elsif @schedule
189
+ setup_schedule(queue)
190
+ else
191
+ #should not reach here
192
+ raise LogStash::ConfigurationError, "Invalid config. Neither interval nor schedule was specified."
193
+ end
194
+ end
195
+
196
+ private
197
+ def setup_interval(queue)
162
198
  @interval_thread = Thread.current
163
199
  Stud.interval(@interval) do
164
200
  run_once(queue)
165
201
  end
166
202
  end
167
203
 
168
- private
204
+ def setup_schedule(queue)
205
+ #schedule hash must contain exactly one of the allowed keys
206
+ msg_invalid_schedule = "Invalid config. schedule hash must contain " +
207
+ "exactly one of the following keys - cron, at, every or in"
208
+ raise Logstash::ConfigurationError, msg_invalid_schedule if @schedule.keys.length !=1
209
+ schedule_type = @schedule.keys.first
210
+ schedule_value = @schedule[schedule_type]
211
+ raise LogStash::ConfigurationError, msg_invalid_schedule unless Schedule_types.include?(schedule_type)
212
+
213
+ @scheduler = Rufus::Scheduler.new(:max_work_threads => 1)
214
+ #as of v3.0.9, :first_in => :now doesn't work. Use the following workaround instead
215
+ opts = schedule_type == "every" ? { :first_in => 0.01 } : {}
216
+ @scheduler.send(schedule_type, schedule_value, opts) { run_once(queue) }
217
+ @scheduler.join
218
+ end
219
+
169
220
  def run_once(queue)
170
221
  @requests.each do |name, request|
171
222
  request_async(queue, name, request)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-http_poller'
3
- s.version = '3.0.3'
3
+ s.version = '3.1.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Poll HTTP endpoints with Logstash."
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"
@@ -22,8 +22,10 @@ Gem::Specification.new do |s|
22
22
  s.add_runtime_dependency 'logstash-codec-plain'
23
23
  s.add_runtime_dependency 'logstash-mixin-http_client', ">= 2.2.4", "< 5.0.0"
24
24
  s.add_runtime_dependency 'stud', "~> 0.0.22"
25
+ s.add_runtime_dependency 'rufus-scheduler', "~>3.0.9"
25
26
 
26
27
  s.add_development_dependency 'logstash-codec-json'
27
28
  s.add_development_dependency 'logstash-devutils'
28
29
  s.add_development_dependency 'flores'
30
+ s.add_development_dependency 'timecop'
29
31
  end
@@ -1,11 +1,14 @@
1
1
  require "logstash/devutils/rspec/spec_helper"
2
2
  require 'logstash/inputs/http_poller'
3
3
  require 'flores/random'
4
+ require "timecop"
4
5
 
5
6
  describe LogStash::Inputs::HTTP_Poller do
6
7
  let(:metadata_target) { "_http_poller_metadata" }
7
8
  let(:queue) { Queue.new }
8
- let(:default_interval) { 5 }
9
+ let(:default_schedule) {
10
+ { "cron" => "* * * * * UTC" }
11
+ }
9
12
  let(:default_name) { "url1 " }
10
13
  let(:default_url) { "http://localhost:1827" }
11
14
  let(:default_urls) {
@@ -15,7 +18,7 @@ describe LogStash::Inputs::HTTP_Poller do
15
18
  }
16
19
  let(:default_opts) {
17
20
  {
18
- "interval" => default_interval,
21
+ "schedule" => default_schedule,
19
22
  "urls" => default_urls,
20
23
  "codec" => "json",
21
24
  "metadata_target" => metadata_target
@@ -31,9 +34,13 @@ describe LogStash::Inputs::HTTP_Poller do
31
34
  end
32
35
 
33
36
  describe "#run" do
34
- it "should run at the specified interval" do
35
- expect(Stud).to receive(:interval).with(default_interval).once
36
- subject.run(double("queue"))
37
+ it "should setup a scheduler" do
38
+ runner = Thread.new do
39
+ subject.run(double("queue"))
40
+ expect(subject.instance_variable_get("@scheduler")).to be_a_kind_of(Rufus::Scheduler)
41
+ end
42
+ runner.kill
43
+ runner.join
37
44
  end
38
45
  end
39
46
 
@@ -151,6 +158,163 @@ describe LogStash::Inputs::HTTP_Poller do
151
158
  end
152
159
  end
153
160
 
161
+ describe "scheduler configuration" do
162
+ context "given an interval" do
163
+ let(:opts) {
164
+ {
165
+ "interval" => 2,
166
+ "urls" => default_urls,
167
+ "codec" => "json",
168
+ "metadata_target" => metadata_target
169
+ }
170
+ }
171
+ it "should run once in each interval" do
172
+ instance = klass.new(opts)
173
+ instance.register
174
+ queue = Queue.new
175
+ runner = Thread.new do
176
+ instance.run(queue)
177
+ end
178
+ #T 0123456
179
+ #events x x x x
180
+ #expects 3 events at T=5
181
+ sleep 5
182
+ instance.stop
183
+ runner.kill
184
+ runner.join
185
+ expect(queue.size).to eq(3)
186
+ end
187
+ end
188
+
189
+ context "given both interval and schedule options" do
190
+ let(:opts) {
191
+ {
192
+ "interval" => 1,
193
+ "schedule" => { "every" => "5s" },
194
+ "urls" => default_urls,
195
+ "codec" => "json",
196
+ "metadata_target" => metadata_target
197
+ }
198
+ }
199
+ it "should raise ConfigurationError" do
200
+ instance = klass.new(opts)
201
+ instance.register
202
+ queue = Queue.new
203
+ runner = Thread.new do
204
+ expect{instance.run(queue)}.to raise_error(LogStash::ConfigurationError)
205
+ end
206
+ instance.stop
207
+ runner.kill
208
+ runner.join
209
+ end
210
+ end
211
+
212
+ context "given 'cron' expression" do
213
+ let(:opts) {
214
+ {
215
+ "schedule" => { "cron" => "* * * * * UTC" },
216
+ "urls" => default_urls,
217
+ "codec" => "json",
218
+ "metadata_target" => metadata_target
219
+ }
220
+ }
221
+ it "should run at the schedule" do
222
+ instance = klass.new(opts)
223
+ instance.register
224
+ Timecop.travel(Time.new(2000,1,1,0,0,0,'+00:00'))
225
+ Timecop.scale(60)
226
+ queue = Queue.new
227
+ runner = Thread.new do
228
+ instance.run(queue)
229
+ end
230
+ sleep 3
231
+ instance.stop
232
+ runner.kill
233
+ runner.join
234
+ expect(queue.size).to eq(2)
235
+ Timecop.return
236
+ end
237
+ end
238
+
239
+ context "given 'at' expression" do
240
+ let(:opts) {
241
+ {
242
+ "schedule" => { "at" => "2000-01-01 00:05:00 +0000"},
243
+ "urls" => default_urls,
244
+ "codec" => "json",
245
+ "metadata_target" => metadata_target
246
+ }
247
+ }
248
+ it "should run at the schedule" do
249
+ instance = klass.new(opts)
250
+ instance.register
251
+ Timecop.travel(Time.new(2000,1,1,0,0,0,'+00:00'))
252
+ Timecop.scale(60 * 5)
253
+ queue = Queue.new
254
+ runner = Thread.new do
255
+ instance.run(queue)
256
+ end
257
+ sleep 2
258
+ instance.stop
259
+ runner.kill
260
+ runner.join
261
+ expect(queue.size).to eq(1)
262
+ Timecop.return
263
+ end
264
+ end
265
+
266
+ context "given 'every' expression" do
267
+ let(:opts) {
268
+ {
269
+ "schedule" => { "every" => "2s"},
270
+ "urls" => default_urls,
271
+ "codec" => "json",
272
+ "metadata_target" => metadata_target
273
+ }
274
+ }
275
+ it "should run at the schedule" do
276
+ instance = klass.new(opts)
277
+ instance.register
278
+ queue = Queue.new
279
+ runner = Thread.new do
280
+ instance.run(queue)
281
+ end
282
+ #T 0123456
283
+ #events x x x x
284
+ #expects 3 events at T=5
285
+ sleep 5
286
+ instance.stop
287
+ runner.kill
288
+ runner.join
289
+ expect(queue.size).to eq(3)
290
+ end
291
+ end
292
+
293
+ context "given 'in' expression" do
294
+ let(:opts) {
295
+ {
296
+ "schedule" => { "in" => "2s"},
297
+ "urls" => default_urls,
298
+ "codec" => "json",
299
+ "metadata_target" => metadata_target
300
+ }
301
+ }
302
+ it "should run at the schedule" do
303
+ instance = klass.new(opts)
304
+ instance.register
305
+ queue = Queue.new
306
+ runner = Thread.new do
307
+ instance.run(queue)
308
+ end
309
+ sleep 3
310
+ instance.stop
311
+ runner.kill
312
+ runner.join
313
+ expect(queue.size).to eq(1)
314
+ end
315
+ end
316
+ end
317
+
154
318
  describe "events" do
155
319
  shared_examples("matching metadata") {
156
320
  let(:metadata) { event.get(metadata_target) }
@@ -292,7 +456,9 @@ describe LogStash::Inputs::HTTP_Poller do
292
456
  }
293
457
  let(:opts) {
294
458
  {
295
- "interval" => default_interval,
459
+ "schedule" => {
460
+ "cron" => "* * * * * UTC"
461
+ },
296
462
  "urls" => {
297
463
  default_name => url
298
464
  },
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-http_poller
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.3
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-21 00:00:00.000000000 Z
12
+ date: 2016-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -79,6 +79,20 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: 0.0.22
82
+ - !ruby/object:Gem::Dependency
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: 3.0.9
88
+ name: rufus-scheduler
89
+ prerelease: false
90
+ type: :runtime
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 3.0.9
82
96
  - !ruby/object:Gem::Dependency
83
97
  requirement: !ruby/object:Gem::Requirement
84
98
  requirements:
@@ -121,6 +135,20 @@ dependencies:
121
135
  - - ">="
122
136
  - !ruby/object:Gem::Version
123
137
  version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ name: timecop
145
+ prerelease: false
146
+ type: :development
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
124
152
  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
125
153
  email: info@elastic.co
126
154
  executables: []