logstash-core 2.3.4.snapshot1-java → 2.4.0-java

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.

Potentially problematic release.


This version of logstash-core might be problematic. Click here for more details.

@@ -392,7 +392,7 @@ module LogStash; class Pipeline
392
392
  def shutdown_workers
393
393
  # Each worker thread will receive this exactly once!
394
394
  @worker_threads.each do |t|
395
- @logger.debug("Pushing shutdown", :thread => t)
395
+ @logger.debug("Pushing shutdown", :thread => t.inspect)
396
396
  @input_queue.push(LogStash::SHUTDOWN)
397
397
  end
398
398
 
@@ -2,6 +2,7 @@
2
2
  require "logstash/namespace"
3
3
  require "logstash/logging"
4
4
  require "logstash/config/mixin"
5
+ require "logstash/instrument/null_metric"
5
6
  require "cabin"
6
7
  require "concurrent"
7
8
 
@@ -26,13 +27,14 @@ class LogStash::Plugin
26
27
  def initialize(params=nil)
27
28
  @params = LogStash::Util.deep_clone(params)
28
29
  @logger = Cabin::Channel.get(LogStash)
30
+ @metric_plugin = LogStash::Instrument::NullMetric.new
29
31
  end
30
32
 
31
33
  # close is called during shutdown, after the plugin worker
32
34
  # main task terminates
33
35
  public
34
36
  def do_close
35
- @logger.debug("closing", :plugin => self)
37
+ @logger.debug("closing", :plugin => self.class.name)
36
38
  close
37
39
  end
38
40
 
@@ -47,6 +49,14 @@ class LogStash::Plugin
47
49
  return "#{self.class.name}: #{@params}"
48
50
  end
49
51
 
52
+ # This is a shim to make sure that plugin
53
+ # that record metric still work with 2.4
54
+ #
55
+ # https://github.com/elastic/logstash/issues/5539
56
+ def metric
57
+ @metric_plugin
58
+ end
59
+
50
60
  public
51
61
  def inspect
52
62
  if !@params.nil?
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+ require "logstash/util"
4
+
5
+ # This class exists to quietly wrap a password string so that, when printed or
6
+ # logged, you don't accidentally print the password itself.
7
+ class LogStash::Util::SafeURI
8
+ PASS_PLACEHOLDER = "xxxxxx".freeze
9
+ HOSTNAME_PORT_REGEX=/\A(?<hostname>([A-Za-z0-9\.\-]+)|\[[0-9A-Fa-f\:]+\])(:(?<port>\d+))?\Z/
10
+
11
+ extend Forwardable
12
+
13
+ def_delegators :@uri, :coerce, :query=, :route_from, :port=, :default_port, :select, :normalize!, :absolute?, :registry=, :path, :password, :hostname, :merge, :normalize, :host, :component_ary, :userinfo=, :query, :set_opaque, :+, :merge!, :-, :password=, :parser, :port, :set_host, :set_path, :opaque=, :scheme, :fragment=, :set_query, :set_fragment, :userinfo, :hostname=, :set_port, :path=, :registry, :opaque, :route_to, :set_password, :hierarchical?, :set_user, :set_registry, :set_userinfo, :fragment, :component, :user=, :set_scheme, :absolute, :host=, :relative?, :scheme=, :user
14
+
15
+ attr_reader :uri
16
+
17
+ public
18
+ def initialize(arg)
19
+ @uri = case arg
20
+ when String
21
+ arg = "//#{arg}" if HOSTNAME_PORT_REGEX.match(arg)
22
+ URI.parse(arg)
23
+ when URI
24
+ arg
25
+ else
26
+ raise ArgumentError, "Expected a string or URI, got a #{arg.class} creating a URL"
27
+ end
28
+ end
29
+
30
+ def to_s
31
+ sanitized.to_s
32
+ end
33
+
34
+ def inspect
35
+ sanitized.to_s
36
+ end
37
+
38
+ def sanitized
39
+ return uri unless uri.password # nothing to sanitize here!
40
+
41
+ safe = uri.clone
42
+ safe.password = PASS_PLACEHOLDER
43
+ safe
44
+ end
45
+
46
+ def ==(other)
47
+ other.is_a?(::LogStash::Util::SafeURI) ? @uri == other.uri : false
48
+ end
49
+ end
50
+
@@ -11,4 +11,4 @@
11
11
  # eventually this file should be in the root logstash lib fir and dependencies in logstash-core should be
12
12
  # fixed.
13
13
 
14
- LOGSTASH_VERSION = "2.3.4.snapshot1"
14
+ LOGSTASH_VERSION = "2.4.0"
data/locales/en.yml CHANGED
@@ -225,3 +225,7 @@ en:
225
225
  Print the compiled config ruby code out as a debug log (you must also have --debug enabled).
226
226
  WARNING: This will include any 'password' options passed to plugin configs as plaintext, and may result
227
227
  in plaintext passwords appearing in your logs!
228
+ log-in-json: |+
229
+ Specify that Logstash should write its own logs in JSON form - one
230
+ event per line. If false, Logstash will log using Ruby's
231
+ Object#inspect (not easy to machine-parse)
@@ -17,7 +17,8 @@ Gem::Specification.new do |gem|
17
17
  gem.require_paths = ["lib"]
18
18
  gem.version = LOGSTASH_CORE_VERSION
19
19
 
20
- gem.add_runtime_dependency "logstash-core-event", "2.3.4.snapshot1"
20
+ gem.add_runtime_dependency "logstash-core-event", "2.4.0"
21
+ # gem.add_runtime_dependency "logstash-core-event-java", "2.4.0.dev"
21
22
 
22
23
  gem.add_runtime_dependency "cabin", "~> 0.8.0" #(Apache 2.0 license)
23
24
  gem.add_runtime_dependency "pry", "~> 0.10.1" #(Ruby license)
@@ -26,7 +27,7 @@ Gem::Specification.new do |gem|
26
27
  gem.add_runtime_dependency "filesize", "0.0.4" #(MIT license) for :bytes config validator
27
28
  gem.add_runtime_dependency "gems", "~> 0.8.3" #(MIT license)
28
29
  gem.add_runtime_dependency "concurrent-ruby", "0.9.2"
29
- gem.add_runtime_dependency "jruby-openssl", "0.9.13" # Required to support TLSv1.2
30
+ gem.add_runtime_dependency "jruby-openssl", "0.9.16" # >= 0.9.13 Required to support TLSv1.2
30
31
 
31
32
  # TODO(sissel): Treetop 1.5.x doesn't seem to work well, but I haven't
32
33
  # investigated what the cause might be. -Jordan
@@ -255,7 +255,7 @@ describe LogStash::Agent do
255
255
  it "should fail with single invalid dir path" do
256
256
  expect(File).to receive(:directory?).and_return(false)
257
257
  expect(LogStash::Environment).not_to receive(:add_plugin_path)
258
- expect{subject.configure_plugin_paths(single_path)}.to raise_error(LogStash::ConfigurationError)
258
+ expect{subject.configure_plugin_paths(single_path)}.to raise_error(Clamp::UsageError)
259
259
  end
260
260
 
261
261
  it "should add multiple valid dir path to the environment" do
@@ -293,15 +293,15 @@ describe LogStash::Agent do
293
293
  it "should fail with single invalid dir path" do
294
294
  expect(File).to receive(:directory?).and_return(false)
295
295
  expect(LogStash::Environment).not_to receive(:add_plugin_path)
296
- expect{subject.configure_plugin_paths(single_path)}.to raise_error(LogStash::ConfigurationError)
296
+ expect{subject.configure_plugin_paths(single_path)}.to raise_error(Clamp::UsageError)
297
297
  end
298
298
  end
299
299
 
300
300
  describe "--config-test" do
301
301
  let(:cli_args) { ["-t", "-e", pipeline_string] }
302
+ let(:pipeline_string) { "input { } filter { } output { }" }
302
303
 
303
304
  context "with a good configuration" do
304
- let(:pipeline_string) { "input { } filter { } output { }" }
305
305
  it "should exit successfuly" do
306
306
  expect(subject.run(cli_args)).to eq(0)
307
307
  end
@@ -313,6 +313,11 @@ describe LogStash::Agent do
313
313
  expect(subject.run(cli_args)).to eq(1)
314
314
  end
315
315
  end
316
+
317
+ it "requests the config loader to format_config" do
318
+ expect(subject.config_loader).to receive(:format_config)
319
+ subject.run(cli_args)
320
+ end
316
321
  end
317
322
 
318
323
  describe "pipeline settings" do
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ DATA_DOUBLE = "data".freeze
5
+
6
+ # use a dummy NOOP output to test Outputs::Base
7
+ class LogStash::Codecs::NOOPAsync < LogStash::Codecs::Base
8
+ attr_reader :last_result
9
+ config_name "noop_async"
10
+
11
+ def encode(event)
12
+ @last_result = @on_event.call(event, DATA_DOUBLE)
13
+ end
14
+ end
15
+
16
+ class LogStash::Codecs::NOOPSync < LogStash::Codecs::Base
17
+ attr_reader :last_result
18
+ config_name "noop_sync"
19
+
20
+ def encode_sync(event)
21
+ DATA_DOUBLE
22
+ end
23
+ end
24
+
25
+ class LogStash::Codecs::NOOPMulti < LogStash::Codecs::Base
26
+ attr_reader :last_result
27
+ config_name "noop_multi"
28
+
29
+ def encode_sync(event)
30
+ DATA_DOUBLE
31
+ end
32
+ end
33
+
34
+ describe LogStash::Codecs::Base do
35
+ let(:params) { {} }
36
+ subject(:instance) { klass.new(params.dup) }
37
+ let(:event) { double("event") }
38
+ let(:encoded_data) { DATA_DOUBLE }
39
+ let(:encoded_tuple) { [event, encoded_data] }
40
+
41
+ describe "encoding" do
42
+ shared_examples "encoder types" do |codec_class|
43
+ let(:klass) { codec_class }
44
+
45
+ describe "#{codec_class}" do
46
+ describe "multi_encode" do
47
+ it "should return an array of [event,data] tuples" do
48
+ expect(instance.multi_encode([event,event])).to eq([encoded_tuple, encoded_tuple])
49
+ end
50
+ end
51
+
52
+ describe "#encode" do
53
+ before do
54
+ @result = nil
55
+ instance.on_event do |event, data|
56
+ @result = [event, data]
57
+ end
58
+ instance.encode(event)
59
+ end
60
+
61
+ it "should yield the correct result" do
62
+ expect(@result).to eq(encoded_tuple)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ include_examples("encoder types", LogStash::Codecs::NOOPAsync)
69
+ include_examples("encoder types", LogStash::Codecs::NOOPSync)
70
+ include_examples("encoder types", LogStash::Codecs::NOOPMulti)
71
+ end
72
+ end
73
+
74
+
@@ -68,6 +68,74 @@ describe LogStash::Config::Mixin do
68
68
  end
69
69
  end
70
70
 
71
+ context "when validating lists of items" do
72
+ let(:klass) do
73
+ Class.new(LogStash::Filters::Base) do
74
+ config_name "multiuri"
75
+ config :uris, :validate => :uri, :list => true
76
+ config :strings, :validate => :string, :list => true
77
+ config :required_strings, :validate => :string, :list => true, :required => true
78
+ end
79
+ end
80
+
81
+ let(:uris) { ["http://example.net/1", "http://example.net/2"] }
82
+ let(:safe_uris) { uris.map {|str| ::LogStash::Util::SafeURI.new(str) } }
83
+ let(:strings) { ["I am a", "modern major general"] }
84
+ let(:required_strings) { ["required", "strings"] }
85
+
86
+ subject { klass.new("uris" => uris, "strings" => strings, "required_strings" => required_strings) }
87
+
88
+ it "a URI list should return an array of URIs" do
89
+ expect(subject.uris).to match_array(safe_uris)
90
+ end
91
+
92
+ it "a string list should return an array of strings" do
93
+ expect(subject.strings).to match_array(strings)
94
+ end
95
+
96
+ context "with a scalar value" do
97
+ let(:strings) { "foo" }
98
+
99
+ it "should return the scalar value as a single element array" do
100
+ expect(subject.strings).to match_array([strings])
101
+ end
102
+ end
103
+
104
+ context "with an empty list" do
105
+ let(:strings) { [] }
106
+
107
+ it "should return nil" do
108
+ expect(subject.strings).to be_nil
109
+ end
110
+ end
111
+
112
+ describe "with required => true" do
113
+ context "and a single element" do
114
+ let(:required_strings) { ["foo"] }
115
+
116
+ it "should return the single value" do
117
+ expect(subject.required_strings).to eql(required_strings)
118
+ end
119
+ end
120
+
121
+ context "with an empty list" do
122
+ let (:required_strings) { [] }
123
+
124
+ it "should raise a configuration error" do
125
+ expect { subject.required_strings }.to raise_error(LogStash::ConfigurationError)
126
+ end
127
+ end
128
+
129
+ context "with no value specified" do
130
+ let (:required_strings) { nil }
131
+
132
+ it "should raise a configuration error" do
133
+ expect { subject.required_strings }.to raise_error(LogStash::ConfigurationError)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
71
139
  context "when validating :password" do
72
140
  let(:klass) do
73
141
  Class.new(LogStash::Filters::Base) do
@@ -102,6 +170,95 @@ describe LogStash::Config::Mixin do
102
170
  end
103
171
  end
104
172
 
173
+ context "when validating :uri" do
174
+ let(:klass) do
175
+ Class.new(LogStash::Filters::Base) do
176
+ config_name "fakeuri"
177
+ config :uri, :validate => :uri
178
+ end
179
+ end
180
+
181
+ shared_examples("safe URI") do |options|
182
+ options ||= {}
183
+
184
+ subject { klass.new("uri" => uri_str) }
185
+
186
+ it "should be a SafeURI object" do
187
+ expect(subject.uri).to(be_a(LogStash::Util::SafeURI))
188
+ end
189
+
190
+ it "should correctly copy URI types" do
191
+ clone = subject.class.new(subject.params)
192
+ expect(clone.uri.to_s).to eql(uri_hidden)
193
+ end
194
+
195
+ it "should make the real URI object availale under #uri" do
196
+ expect(subject.uri.uri).to be_a(::URI)
197
+ end
198
+
199
+ it "should obfuscate original_params" do
200
+ expect(subject.original_params['uri']).to(be_a(LogStash::Util::SafeURI))
201
+ end
202
+
203
+ if !options[:exclude_password_specs]
204
+ describe "passwords" do
205
+ it "should make password values hidden with #to_s" do
206
+ expect(subject.uri.to_s).to eql(uri_hidden)
207
+ end
208
+
209
+ it "should make password values hidden with #inspect" do
210
+ expect(subject.uri.inspect).to eql(uri_hidden)
211
+ end
212
+ end
213
+ end
214
+
215
+ context "attributes" do
216
+ [:scheme, :user, :password, :hostname, :path].each do |attr|
217
+ it "should make #{attr} available" do
218
+ expect(subject.uri.send(attr)).to eql(self.send(attr))
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ context "with a host:port combination" do
225
+ let(:scheme) { nil }
226
+ let(:user) { nil }
227
+ let(:password) { nil }
228
+ let(:hostname) { "myhostname" }
229
+ let(:port) { 1234 }
230
+ let(:path) { "" }
231
+ let(:uri_str) { "#{hostname}:#{port}" }
232
+ let(:uri_hidden) { "//#{hostname}:#{port}" }
233
+
234
+ include_examples("safe URI", :exclude_password_specs => true)
235
+ end
236
+
237
+ context "with a username / password" do
238
+ let(:scheme) { "myscheme" }
239
+ let(:user) { "myuser" }
240
+ let(:password) { "fancypants" }
241
+ let(:hostname) { "myhostname" }
242
+ let(:path) { "/my/path" }
243
+ let(:uri_str) { "#{scheme}://#{user}:#{password}@#{hostname}#{path}" }
244
+ let(:uri_hidden) { "#{scheme}://#{user}:#{LogStash::Util::SafeURI::PASS_PLACEHOLDER}@#{hostname}#{path}" }
245
+
246
+ include_examples("safe URI")
247
+ end
248
+
249
+ context "without a username / password" do
250
+ let(:scheme) { "myscheme" }
251
+ let(:user) { nil }
252
+ let(:password) { nil }
253
+ let(:hostname) { "myhostname" }
254
+ let(:path) { "/my/path" }
255
+ let(:uri_str) { "#{scheme}://#{hostname}#{path}" }
256
+ let(:uri_hidden) { "#{scheme}://#{hostname}#{path}" }
257
+
258
+ include_examples("safe URI")
259
+ end
260
+ end
261
+
105
262
  describe "obsolete settings" do
106
263
  let(:plugin_class) do
107
264
  Class.new(LogStash::Inputs::Base) do
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ require "logstash/instrument/null_metric"
3
+
4
+ describe LogStash::Instrument::NullMetric do
5
+ let(:key) { "galaxy" }
6
+
7
+ describe "#increment" do
8
+ it "allows to increment a key with no amount" do
9
+ expect { subject.increment(key, 100) }.not_to raise_error
10
+ end
11
+
12
+ it "allow to increment a key" do
13
+ expect { subject.increment(key) }.not_to raise_error
14
+ end
15
+ end
16
+
17
+ describe "#decrement" do
18
+ it "allows to decrement a key with no amount" do
19
+ expect { subject.decrement(key, 100) }.not_to raise_error
20
+ end
21
+
22
+ it "allow to decrement a key" do
23
+ expect { subject.decrement(key) }.not_to raise_error
24
+ end
25
+ end
26
+
27
+ describe "#gauge" do
28
+ it "allows to set a value" do
29
+ expect { subject.gauge(key, "pluto") }.not_to raise_error
30
+ end
31
+ end
32
+
33
+ describe "#report_time" do
34
+ it "allow to record time" do
35
+ expect { subject.report_time(key, 1000) }.not_to raise_error
36
+ end
37
+ end
38
+
39
+ describe "#time" do
40
+ it "allow to record time with a block given" do
41
+ expect do
42
+ subject.time(key) { 1+1 }
43
+ end.not_to raise_error
44
+ end
45
+
46
+ it "when using a block it return the generated value" do
47
+ expect(subject.time(key) { 1+1 }).to eq(2)
48
+ end
49
+
50
+ it "allow to record time with no block given" do
51
+ expect do
52
+ clock = subject.time(key)
53
+ clock.stop
54
+ end.not_to raise_error
55
+ end
56
+ end
57
+
58
+ describe "#namespace" do
59
+ it "return a NullMetric" do
60
+ expect(subject.namespace(key)).to be_kind_of LogStash::Instrument::NullMetric
61
+ end
62
+ end
63
+ end