logstash-core 5.0.0.alpha3.snapshot2-java → 5.0.0.alpha3.snapshot4-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/version.rb +1 -1
  3. data/lib/logstash/agent.rb +49 -31
  4. data/lib/logstash/api/init.ru +3 -3
  5. data/lib/logstash/api/lib/app/service.rb +1 -1
  6. data/lib/logstash/config/config_ast.rb +23 -18
  7. data/lib/logstash/config/loader.rb +4 -4
  8. data/lib/logstash/config/mixin.rb +10 -21
  9. data/lib/logstash/environment.rb +30 -0
  10. data/lib/logstash/filters/base.rb +2 -2
  11. data/lib/logstash/inputs/base.rb +2 -2
  12. data/lib/logstash/instrument/collector.rb +1 -1
  13. data/lib/logstash/logging/json.rb +21 -0
  14. data/lib/logstash/output_delegator.rb +2 -2
  15. data/lib/logstash/patches/clamp.rb +69 -0
  16. data/lib/logstash/pipeline.rb +37 -62
  17. data/lib/logstash/plugin.rb +1 -1
  18. data/lib/logstash/runner.rb +155 -146
  19. data/lib/logstash/settings.rb +267 -0
  20. data/lib/logstash/util/decorators.rb +6 -6
  21. data/lib/logstash/util/java_version.rb +1 -10
  22. data/lib/logstash/util/worker_threads_default_printer.rb +2 -2
  23. data/lib/logstash/version.rb +1 -1
  24. data/locales/en.yml +17 -20
  25. data/logstash-core.gemspec +1 -1
  26. data/spec/api/spec_helper.rb +15 -16
  27. data/spec/conditionals_spec.rb +113 -113
  28. data/spec/logstash/agent_spec.rb +77 -68
  29. data/spec/logstash/config/config_ast_spec.rb +4 -2
  30. data/spec/logstash/config/mixin_spec.rb +33 -7
  31. data/spec/logstash/filters/base_spec.rb +16 -16
  32. data/spec/logstash/inputs/base_spec.rb +8 -8
  33. data/spec/logstash/output_delegator_spec.rb +2 -0
  34. data/spec/logstash/pipeline_spec.rb +60 -26
  35. data/spec/logstash/plugin_spec.rb +2 -2
  36. data/spec/logstash/runner_spec.rb +112 -25
  37. data/spec/logstash/setting_spec.rb +130 -0
  38. data/spec/logstash/settings_spec.rb +62 -0
  39. metadata +11 -9
  40. data/lib/logstash/util/defaults_printer.rb +0 -31
  41. data/spec/logstash/util/defaults_printer_spec.rb +0 -50
  42. data/spec/logstash/util/worker_threads_default_printer_spec.rb +0 -45
@@ -0,0 +1,267 @@
1
+ # encoding: utf-8
2
+
3
+ module LogStash
4
+ class Settings
5
+
6
+ def initialize
7
+ @settings = {}
8
+ end
9
+
10
+ def register(setting)
11
+ if @settings.key?(setting.name)
12
+ raise ArgumentError.new("Setting \"#{setting.name}\" has already been registered as #{setting.inspect}")
13
+ else
14
+ @settings[setting.name] = setting
15
+ end
16
+ end
17
+
18
+ def get_setting(setting_name)
19
+ setting = @settings[setting_name]
20
+ raise ArgumentError.new("Setting \"#{setting_name}\" hasn't been registered") if setting.nil?
21
+ setting
22
+ end
23
+
24
+ def get_subset(setting_regexp)
25
+ regexp = setting_regexp.is_a?(Regexp) ? setting_regexp : Regexp.new(setting_regexp)
26
+ settings = self.class.new
27
+ @settings.each do |setting_name, setting|
28
+ next unless setting_name.match(regexp)
29
+ settings.register(setting.clone)
30
+ end
31
+ settings
32
+ end
33
+
34
+ def set?(setting_name)
35
+ get_setting(setting_name).set?
36
+ end
37
+
38
+ def clone
39
+ get_subset(".*")
40
+ end
41
+
42
+ def get_default(setting_name)
43
+ get_setting(setting_name).default
44
+ end
45
+
46
+ def get_value(setting_name)
47
+ get_setting(setting_name).value
48
+ end
49
+ alias_method :get, :get_value
50
+
51
+ def set_value(setting_name, value)
52
+ get_setting(setting_name).set(value)
53
+ end
54
+ alias_method :set, :set_value
55
+
56
+ def to_hash
57
+ hash = {}
58
+ @settings.each do |name, setting|
59
+ hash[name] = setting.value
60
+ end
61
+ hash
62
+ end
63
+
64
+ def merge(hash)
65
+ hash.each {|key, value| set_value(key, value) }
66
+ self
67
+ end
68
+
69
+ def format_settings
70
+ output = []
71
+ output << "-------- Logstash Settings (* means modified) ---------"
72
+ @settings.each do |setting_name, setting|
73
+ value = setting.value
74
+ default_value = setting.default
75
+ if default_value == value # print setting and its default value
76
+ output << "#{setting_name}: #{value.inspect}" unless value.nil?
77
+ elsif default_value.nil? # print setting and warn it has been set
78
+ output << "*#{setting_name}: #{value.inspect}"
79
+ elsif value.nil? # default setting not set by user
80
+ output << "#{setting_name}: #{default_value.inspect}"
81
+ else # print setting, warn it has been set, and show default value
82
+ output << "*#{setting_name}: #{value.inspect} (default: #{default_value.inspect})"
83
+ end
84
+ end
85
+ output << "--------------- Logstash Settings -------------------"
86
+ output
87
+ end
88
+
89
+ def reset
90
+ @settings.values.each(&:reset)
91
+ end
92
+
93
+ def from_yaml(yaml_path)
94
+ settings = read_yaml(::File.join(yaml_path, "logstash.yml"))
95
+ self.merge(flatten_hash(settings))
96
+ end
97
+
98
+ private
99
+ def read_yaml(path)
100
+ YAML.safe_load(IO.read(path)) || {}
101
+ end
102
+
103
+ def flatten_hash(h,f="",g={})
104
+ return g.update({ f => h }) unless h.is_a? Hash
105
+ if f.empty?
106
+ h.each { |k,r| flatten_hash(r,k,g) }
107
+ else
108
+ h.each { |k,r| flatten_hash(r,"#{f}.#{k}",g) }
109
+ end
110
+ g
111
+ end
112
+ end
113
+
114
+ class Setting
115
+ attr_reader :name, :default
116
+
117
+ def initialize(name, klass, default=nil, strict=true, &validator_proc)
118
+ @name = name
119
+ unless klass.is_a?(Class)
120
+ raise ArgumentError.new("Setting \"#{@name}\" must be initialized with a class (received #{klass})")
121
+ end
122
+ @klass = klass
123
+ @validator_proc = validator_proc
124
+ @value = nil
125
+ @value_is_set = false
126
+
127
+ validate(default) if strict
128
+ @default = default
129
+ end
130
+
131
+ def value
132
+ @value_is_set ? @value : default
133
+ end
134
+
135
+ def set?
136
+ @value_is_set
137
+ end
138
+
139
+ def set(value)
140
+ validate(value)
141
+ @value = value
142
+ @value_is_set = true
143
+ @value
144
+ end
145
+
146
+ def reset
147
+ @value = nil
148
+ @value_is_set = false
149
+ end
150
+
151
+ def to_hash
152
+ {
153
+ "name" => @name,
154
+ "klass" => @klass,
155
+ "value" => @value,
156
+ "value_is_set" => @value_is_set,
157
+ "default" => @default,
158
+ # Proc#== will only return true if it's the same obj
159
+ # so no there's no point in comparing it
160
+ # also thereś no use case atm to return the proc
161
+ # so let's not expose it
162
+ #"validator_proc" => @validator_proc
163
+ }
164
+ end
165
+
166
+ def ==(other)
167
+ self.to_hash == other.to_hash
168
+ end
169
+
170
+ private
171
+ def validate(value)
172
+ if !value.is_a?(@klass)
173
+ raise ArgumentError.new("Setting \"#{@name}\" must be a #{@klass}. Received: #{value} (#{value.class})")
174
+ elsif @validator_proc && !@validator_proc.call(value)
175
+ raise ArgumentError.new("Failed to validate setting \"#{@name}\" with value: #{value}")
176
+ end
177
+ end
178
+
179
+ ### Specific settings #####
180
+
181
+ class Boolean < Setting
182
+ def initialize(name, default, strict=true, &validator_proc)
183
+ @name = name
184
+ @klass = Object
185
+ @value = nil
186
+ @value_is_set = false
187
+ @validator_proc = validator_proc
188
+ coerced_default = coerce(default)
189
+ validate(coerced_default)
190
+ @default = coerced_default
191
+ end
192
+
193
+ def coerce(value)
194
+ case value
195
+ when TrueClass, "true"
196
+ true
197
+ when FalseClass, "false"
198
+ false
199
+ else
200
+ raise ArgumentError.new("could not coerce #{value} into a boolean")
201
+ end
202
+ end
203
+
204
+ def set(value)
205
+ coerced_value = coerce(value)
206
+ validate(coerced_value)
207
+ @value = coerce(coerced_value)
208
+ @value_is_set = true
209
+ @value
210
+ end
211
+ end
212
+
213
+ class String < Setting
214
+ def initialize(name, default=nil, strict=true)
215
+ super(name, ::String, default, strict)
216
+ end
217
+ end
218
+
219
+ class Numeric < Setting
220
+ def initialize(name, default=nil, strict=true)
221
+ super(name, ::Numeric, default, strict)
222
+ end
223
+ end
224
+
225
+ class Port < Setting
226
+ def initialize(name, default=nil, strict=true)
227
+ super(name, ::Numeric, default, strict) {|value| value >= 1 && value <= 65535 }
228
+ end
229
+ end
230
+
231
+ class Validator < Setting
232
+ def initialize(name, default=nil, strict=true, validator_class=nil)
233
+ @validator_class = validator_class
234
+ super(name, ::Object, default, strict)
235
+ end
236
+
237
+ def validate(value)
238
+ @validator_class.validate(value)
239
+ end
240
+ end
241
+
242
+ class String < Setting
243
+ def initialize(name, default=nil, strict=true, possible_strings=[])
244
+ super(name, ::String, default, strict)
245
+ end
246
+
247
+ def validate(value)
248
+ super(value) && possible_strings.include?(value)
249
+ end
250
+ end
251
+
252
+ class ExistingFilePath < Setting
253
+ def initialize(name, default=nil, strict=true)
254
+ super(name, ::String, default, strict) do |file_path|
255
+ if !::File.exists?(file_path)
256
+ raise ::ArgumentError.new("File \"#{file_path}\" must exist but was not found.")
257
+ else
258
+ true
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ end
265
+
266
+ SETTINGS = Settings.new
267
+ end
@@ -7,7 +7,7 @@ module LogStash::Util
7
7
  # Decorators provides common manipulation on the event data.
8
8
  module Decorators
9
9
  extend self
10
-
10
+
11
11
  @logger = Cabin::Channel.get(LogStash)
12
12
 
13
13
  # fields is a hash of field => value
@@ -22,11 +22,11 @@ module LogStash::Util
22
22
  # note below that the array field needs to be updated then reassigned to the event.
23
23
  # this is important because a construct like event[field] << v will not work
24
24
  # in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140
25
- a = Array(event[field])
25
+ a = Array(event.get(field))
26
26
  a << v
27
- event[field] = a
27
+ event.set(field, a)
28
28
  else
29
- event[field] = v
29
+ event.set(field, v)
30
30
  end
31
31
  @logger.debug? and @logger.debug("#{pluginname}: adding value to field", :field => field, :value => value)
32
32
  end
@@ -41,9 +41,9 @@ module LogStash::Util
41
41
  # note below that the tags array field needs to be updated then reassigned to the event.
42
42
  # this is important because a construct like event["tags"] << tag will not work
43
43
  # in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140
44
- tags = event["tags"] || []
44
+ tags = event.get("tags") || []
45
45
  tags << tag
46
- event["tags"] = tags
46
+ event.set("tags", tags)
47
47
  end
48
48
  end
49
49
 
@@ -5,16 +5,7 @@ module LogStash::Util::JavaVersion
5
5
  def self.logger
6
6
  @logger ||= Cabin::Channel.get(LogStash)
7
7
  end
8
-
9
- # Print a warning if we're on a bad version of java
10
- def self.warn_on_bad_java_version
11
- if self.bad_java_version?(self.version)
12
- msg = "!!! Please upgrade your java version, the current version '#{self.version}' is not supported. We recommend a minimum version of Java 8"
13
- STDERR.puts(msg)
14
- logger.warn(msg)
15
- end
16
- end
17
-
8
+
18
9
  # Return the current java version string. Returns nil if this is a non-java platform (e.g. MRI).
19
10
  def self.version
20
11
  return nil unless LogStash::Environment.jruby?
@@ -6,8 +6,8 @@ require "logstash/util"
6
6
  module LogStash module Util class WorkerThreadsDefaultPrinter
7
7
 
8
8
  def initialize(settings)
9
- @setting = settings.fetch(:pipeline_workers, 0)
10
- @default = settings.fetch(:default_pipeline_workers, 0)
9
+ @setting = settings.fetch('pipeline.workers', 0)
10
+ @default = settings.fetch('default-pipeline-workers', 0)
11
11
  end
12
12
 
13
13
  def visit(collector)
@@ -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 = "5.0.0-alpha3.snapshot2"
14
+ LOGSTASH_VERSION = "5.0.0-alpha3.snapshot4"
@@ -71,12 +71,8 @@ en:
71
71
  non_reloadable_config_reload: >-
72
72
  Unable to reload configuration because it does not support dynamic reloading
73
73
  non_reloadable_config_register: |-
74
- Logstash was not able to load configuration since it does not support
75
- dynamic reloading and -r or --auto-reload flag was enabled
74
+ Logstash is not able to start since configuration auto reloading was enabled but the configuration contains plugins that don't support it. Quitting...
76
75
  web_api:
77
- flag:
78
- http_host: Web API binding host
79
- http_port: Web API http port
80
76
  hot_threads:
81
77
  title: |-
82
78
  ::: {%{hostname}}
@@ -182,10 +178,8 @@ en:
182
178
  the empty string for the '-e' flag.
183
179
  configtest: |+
184
180
  Check configuration for valid syntax and then exit.
185
- allow-env: |+
186
- EXPERIMENTAL. Enables templating of environment variable
187
- values. Instances of "${VAR}" in strings will be replaced
188
- with the respective environment variable value named "VAR".
181
+ http_host: Web API binding host
182
+ http_port: Web API http port
189
183
  pipeline-workers: |+
190
184
  Sets the number of pipeline workers to run.
191
185
  pipeline-batch-size: |+
@@ -193,6 +187,9 @@ en:
193
187
  pipeline-batch-delay: |+
194
188
  When creating pipeline batches, how long to wait while polling
195
189
  for the next event.
190
+ path_settings: |+
191
+ Directory containing logstash.yml file. This can also be
192
+ set through the LS_SETTINGS_DIR environment variable.
196
193
  auto_reload: |+
197
194
  Monitor configuration changes and reload
198
195
  whenever it is changed.
@@ -221,15 +218,12 @@ en:
221
218
  'PATH/logstash/TYPE/NAME.rb' where TYPE is
222
219
  'inputs' 'filters', 'outputs' or 'codecs'
223
220
  and NAME is the name of the plugin.
224
- quiet: |+
225
- Quieter logstash logging. This causes only
226
- errors to be emitted.
227
- verbose: |+
228
- More verbose logging. This causes 'info'
229
- level logs to be emitted.
230
- debug: |+
231
- Most verbose logging. This causes 'debug'
232
- level logs to be emitted.
221
+ log_level: |+
222
+ Set the log level for logstash. Possible values are:
223
+ - quiet => :error
224
+ - verbose => :info
225
+ - debug => :debug
226
+ - warn => :warn
233
227
  unsafe_shutdown: |+
234
228
  Force logstash to exit during shutdown even
235
229
  if there are still inflight events in memory.
@@ -243,7 +237,10 @@ en:
243
237
  it will default to the current hostname.
244
238
  agent: |+
245
239
  Specify an alternate agent plugin name.
246
- debug_config: |+
240
+ config_debug: |+
247
241
  Print the compiled config ruby code out as a debug log (you must also have --debug enabled).
248
242
  WARNING: This will include any 'password' options passed to plugin configs as plaintext, and may result
249
- in plaintext passwords appearing in your logs!
243
+ in plaintext passwords appearing in your logs!
244
+ log_format: |+
245
+ Specify if Logstash should write its own logs in JSON form (one
246
+ event per line) or in plain text (using Ruby's Object#inspect)
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.require_paths = ["lib"]
18
18
  gem.version = LOGSTASH_CORE_VERSION.gsub(/-/, '.')
19
19
 
20
- gem.add_runtime_dependency "logstash-core-event-java", "5.0.0-alpha3.snapshot2"
20
+ gem.add_runtime_dependency "logstash-core-event-java", "5.0.0.alpha3.snapshot4"
21
21
 
22
22
  gem.add_runtime_dependency "cabin", "~> 0.8.0" #(Apache 2.0 license)
23
23
  gem.add_runtime_dependency "pry", "~> 0.10.1" #(Ruby license)
@@ -3,6 +3,7 @@ API_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib",
3
3
 
4
4
  require "logstash/devutils/rspec/spec_helper"
5
5
 
6
+ require "logstash/settings"
6
7
  require 'rack/test'
7
8
  require 'rspec'
8
9
  require "json"
@@ -37,26 +38,24 @@ class LogStashRunner
37
38
  attr_reader :config_str, :agent, :pipeline_settings
38
39
 
39
40
  def initialize
40
- args = [
41
- :logger => Cabin::Channel.get(LogStash),
42
- :auto_reload => false,
43
- :collect_metric => true,
44
- :debug => false,
45
- :node_name => "test_agent",
46
- :web_api_http_port => rand(9600..9700)
47
- ]
48
-
49
41
  @config_str = "input { generator {count => 0} } output { }"
50
- @agent = LogStash::DummyAgent.new(*args)
51
- @pipeline_settings ||= { :pipeline_id => "main",
52
- :config_str => config_str,
53
- :pipeline_batch_size => 1,
54
- :flush_interval => 1,
55
- :pipeline_workers => 1 }
42
+ args = {
43
+ "config.reload.automatic" => false,
44
+ "metric.collect" => true,
45
+ "log.level" => "debug",
46
+ "node.name" => "test_agent",
47
+ "http.port" => rand(9600..9700),
48
+ "config.string" => @config_str,
49
+ "pipeline.batch.size" => 1,
50
+ "pipeline.workers" => 1
51
+ }
52
+ @settings = ::LogStash::SETTINGS.clone.merge(args)
53
+
54
+ @agent = LogStash::DummyAgent.new(@settings)
56
55
  end
57
56
 
58
57
  def start
59
- agent.register_pipeline("main", pipeline_settings)
58
+ agent.register_pipeline("main", @settings)
60
59
  @runner = Thread.new(agent) do |_agent|
61
60
  _agent.execute
62
61
  end