logstash-core 1.5.0.beta2-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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/lib/logstash-event.rb +2 -0
  3. data/lib/logstash.rb +4 -0
  4. data/lib/logstash/JRUBY-PR1448.rb +32 -0
  5. data/lib/logstash/agent.rb +355 -0
  6. data/lib/logstash/bundler.rb +124 -0
  7. data/lib/logstash/codecs/base.rb +50 -0
  8. data/lib/logstash/config/config_ast.rb +508 -0
  9. data/lib/logstash/config/file.rb +39 -0
  10. data/lib/logstash/config/grammar.rb +3503 -0
  11. data/lib/logstash/config/mixin.rb +495 -0
  12. data/lib/logstash/config/registry.rb +13 -0
  13. data/lib/logstash/environment.rb +168 -0
  14. data/lib/logstash/errors.rb +12 -0
  15. data/lib/logstash/event.rb +310 -0
  16. data/lib/logstash/filters/base.rb +239 -0
  17. data/lib/logstash/gemfile.rb +175 -0
  18. data/lib/logstash/inputs/base.rb +137 -0
  19. data/lib/logstash/inputs/threadable.rb +18 -0
  20. data/lib/logstash/java_integration.rb +41 -0
  21. data/lib/logstash/json.rb +53 -0
  22. data/lib/logstash/logging.rb +91 -0
  23. data/lib/logstash/multiqueue.rb +53 -0
  24. data/lib/logstash/namespace.rb +17 -0
  25. data/lib/logstash/outputs/base.rb +124 -0
  26. data/lib/logstash/patches.rb +3 -0
  27. data/lib/logstash/patches/bugfix_jruby_2558.rb +50 -0
  28. data/lib/logstash/patches/cabin.rb +34 -0
  29. data/lib/logstash/patches/profile_require_calls.rb +47 -0
  30. data/lib/logstash/pipeline.rb +305 -0
  31. data/lib/logstash/plugin.rb +177 -0
  32. data/lib/logstash/pluginmanager.rb +17 -0
  33. data/lib/logstash/pluginmanager/install.rb +112 -0
  34. data/lib/logstash/pluginmanager/list.rb +38 -0
  35. data/lib/logstash/pluginmanager/main.rb +22 -0
  36. data/lib/logstash/pluginmanager/maven_tools_patch.rb +12 -0
  37. data/lib/logstash/pluginmanager/uninstall.rb +49 -0
  38. data/lib/logstash/pluginmanager/update.rb +50 -0
  39. data/lib/logstash/pluginmanager/util.rb +88 -0
  40. data/lib/logstash/program.rb +15 -0
  41. data/lib/logstash/runner.rb +167 -0
  42. data/lib/logstash/sized_queue.rb +8 -0
  43. data/lib/logstash/threadwatchdog.rb +37 -0
  44. data/lib/logstash/timestamp.rb +97 -0
  45. data/lib/logstash/util.rb +152 -0
  46. data/lib/logstash/util/accessors.rb +88 -0
  47. data/lib/logstash/util/buftok.rb +139 -0
  48. data/lib/logstash/util/charset.rb +35 -0
  49. data/lib/logstash/util/fieldreference.rb +68 -0
  50. data/lib/logstash/util/filetools.rb +185 -0
  51. data/lib/logstash/util/password.rb +25 -0
  52. data/lib/logstash/util/plugin_version.rb +43 -0
  53. data/lib/logstash/util/prctl.rb +11 -0
  54. data/lib/logstash/util/require-helper.rb +18 -0
  55. data/lib/logstash/util/retryable.rb +39 -0
  56. data/lib/logstash/util/socket_peer.rb +7 -0
  57. data/lib/logstash/version.rb +6 -0
  58. data/locales/en.yml +176 -0
  59. metadata +427 -0
@@ -0,0 +1,495 @@
1
+ # encoding: utf-8
2
+
3
+ require "logstash/namespace"
4
+ require "logstash/config/registry"
5
+ require "logstash/logging"
6
+ require "logstash/util/password"
7
+ require "logstash/version"
8
+ require "logstash/environment"
9
+ require "logstash/util/plugin_version"
10
+ require "filesize"
11
+
12
+ LogStash::Environment.load_locale!
13
+
14
+ # This module is meant as a mixin to classes wishing to be configurable from
15
+ # config files
16
+ #
17
+ # The idea is that you can do this:
18
+ #
19
+ # class Foo < LogStash::Config
20
+ # # Add config file settings
21
+ # config "path" => ...
22
+ # config "tag" => ...
23
+ #
24
+ # # Add global flags (becomes --foo-bar)
25
+ # flag "bar" => ...
26
+ # end
27
+ #
28
+ # And the config file should let you do:
29
+ #
30
+ # foo {
31
+ # "path" => ...
32
+ # "tag" => ...
33
+ # }
34
+ #
35
+ module LogStash::Config::Mixin
36
+ attr_accessor :config
37
+ attr_accessor :original_params
38
+
39
+ CONFIGSORT = {
40
+ Symbol => 0,
41
+ String => 0,
42
+ Regexp => 100,
43
+ }
44
+
45
+ PLUGIN_VERSION_1_0_0 = LogStash::Util::PluginVersion.new(1, 0, 0)
46
+ PLUGIN_VERSION_0_9_0 = LogStash::Util::PluginVersion.new(0, 9, 0)
47
+
48
+ # This method is called when someone does 'include LogStash::Config'
49
+ def self.included(base)
50
+ # Add the DSL methods to the 'base' given.
51
+ base.extend(LogStash::Config::Mixin::DSL)
52
+ end
53
+
54
+ def config_init(params)
55
+ # Validation will modify the values inside params if necessary.
56
+ # For example: converting a string to a number, etc.
57
+
58
+ # Keep a copy of the original config params so that we can later
59
+ # differentiate between explicit configuration and implicit (default)
60
+ # configuration.
61
+ @original_params = params.clone
62
+
63
+ # store the plugin type, turns LogStash::Inputs::Base into 'input'
64
+ @plugin_type = self.class.ancestors.find { |a| a.name =~ /::Base$/ }.config_name
65
+
66
+ # warn about deprecated variable use
67
+ params.each do |name, value|
68
+ opts = self.class.get_config[name]
69
+ if opts && opts[:deprecated]
70
+ extra = opts[:deprecated].is_a?(String) ? opts[:deprecated] : ""
71
+ extra.gsub!("%PLUGIN%", self.class.config_name)
72
+ @logger.warn("You are using a deprecated config setting " +
73
+ "#{name.inspect} set in #{self.class.config_name}. " +
74
+ "Deprecated settings will continue to work, " +
75
+ "but are scheduled for removal from logstash " +
76
+ "in the future. #{extra} If you have any questions " +
77
+ "about this, please visit the #logstash channel " +
78
+ "on freenode irc.", :name => name, :plugin => self)
79
+ end
80
+ end
81
+
82
+ # Set defaults from 'config :foo, :default => somevalue'
83
+ self.class.get_config.each do |name, opts|
84
+ next if params.include?(name.to_s)
85
+ if opts.include?(:default) and (name.is_a?(Symbol) or name.is_a?(String))
86
+ # default values should be cloned if possible
87
+ # cloning prevents
88
+ case opts[:default]
89
+ when FalseClass, TrueClass, NilClass, Numeric
90
+ params[name.to_s] = opts[:default]
91
+ else
92
+ params[name.to_s] = opts[:default].clone
93
+ end
94
+ end
95
+
96
+ # Allow plugins to override default values of config settings
97
+ if self.class.default?(name)
98
+ params[name.to_s] = self.class.get_default(name)
99
+ end
100
+ end
101
+
102
+ if !self.class.validate(params)
103
+ raise LogStash::ConfigurationError,
104
+ I18n.t("logstash.agent.configuration.invalid_plugin_settings")
105
+ end
106
+
107
+ # set instance variables like '@foo' for each config value given.
108
+ params.each do |key, value|
109
+ next if key[0, 1] == "@"
110
+
111
+ # Set this key as an instance variable only if it doesn't start with an '@'
112
+ @logger.debug("config #{self.class.name}/@#{key} = #{value.inspect}")
113
+ instance_variable_set("@#{key}", value)
114
+ end
115
+
116
+ @config = params
117
+ end # def config_init
118
+
119
+ module DSL
120
+ attr_accessor :flags
121
+
122
+ # If name is given, set the name and return it.
123
+ # If no name given (nil), return the current name.
124
+ def config_name(name = nil)
125
+ @config_name = name if !name.nil?
126
+ LogStash::Config::Registry.registry[@config_name] = self
127
+ return @config_name
128
+ end
129
+
130
+ # Deprecated: Declare the version of the plugin
131
+ # inside the gemspec.
132
+ def plugin_status(status = nil)
133
+ milestone(status)
134
+ end
135
+
136
+ # Deprecated: Declare the version of the plugin
137
+ # inside the gemspec.
138
+ def milestone(m = nil)
139
+ @logger = Cabin::Channel.get(LogStash)
140
+ @logger.error(I18n.t('logstash.plugin.deprecated_milestone', :plugin => config_name))
141
+ end
142
+
143
+ # Define a new configuration setting
144
+ def config(name, opts={})
145
+ @config ||= Hash.new
146
+ # TODO(sissel): verify 'name' is of type String, Symbol, or Regexp
147
+
148
+ name = name.to_s if name.is_a?(Symbol)
149
+ @config[name] = opts # ok if this is empty
150
+
151
+ if name.is_a?(String)
152
+ define_method(name) { instance_variable_get("@#{name}") }
153
+ define_method("#{name}=") { |v| instance_variable_set("@#{name}", v) }
154
+ end
155
+ end # def config
156
+
157
+ def default(name, value)
158
+ @defaults ||= {}
159
+ @defaults[name.to_s] = value
160
+ end
161
+
162
+ def get_config
163
+ return @config
164
+ end # def get_config
165
+
166
+ def get_default(name)
167
+ return @defaults && @defaults[name]
168
+ end
169
+
170
+ def default?(name)
171
+ return @defaults && @defaults.include?(name)
172
+ end
173
+
174
+ def options(opts)
175
+ # add any options from this class
176
+ prefix = self.name.split("::").last.downcase
177
+ @flags.each do |flag|
178
+ flagpart = flag[:args].first.gsub(/^--/,"")
179
+ # TODO(sissel): logger things here could help debugging.
180
+
181
+ opts.on("--#{prefix}-#{flagpart}", *flag[:args][1..-1], &flag[:block])
182
+ end
183
+ end # def options
184
+
185
+ # This is called whenever someone subclasses a class that has this mixin.
186
+ def inherited(subclass)
187
+ # Copy our parent's config to a subclass.
188
+ # This method is invoked whenever someone subclasses us, like:
189
+ # class Foo < Bar ...
190
+ subconfig = Hash.new
191
+ if !@config.nil?
192
+ @config.each do |key, val|
193
+ subconfig[key] = val
194
+ end
195
+ end
196
+ subclass.instance_variable_set("@config", subconfig)
197
+ @@version_notice_given = false
198
+ end # def inherited
199
+
200
+ def validate(params)
201
+ @plugin_name = config_name
202
+ @plugin_type = ancestors.find { |a| a.name =~ /::Base$/ }.config_name
203
+ @logger = Cabin::Channel.get(LogStash)
204
+ is_valid = true
205
+
206
+ print_version_notice
207
+
208
+ is_valid &&= validate_check_invalid_parameter_names(params)
209
+ is_valid &&= validate_check_required_parameter_names(params)
210
+ is_valid &&= validate_check_parameter_values(params)
211
+
212
+ return is_valid
213
+ end # def validate
214
+
215
+ def print_version_notice
216
+ return if @@version_notice_given
217
+
218
+ begin
219
+ plugin_version = LogStash::Util::PluginVersion.find_plugin_version!(@plugin_type, @config_name)
220
+
221
+ if plugin_version < PLUGIN_VERSION_1_0_0
222
+ if plugin_version < PLUGIN_VERSION_0_9_0
223
+ @logger.info(I18n.t("logstash.plugin.version.0-1-x",
224
+ :type => @plugin_type,
225
+ :name => @config_name,
226
+ :LOGSTASH_VERSION => LOGSTASH_VERSION))
227
+ else
228
+ @logger.info(I18n.t("logstash.plugin.version.0-9-x",
229
+ :type => @plugin_type,
230
+ :name => @config_name,
231
+ :LOGSTASH_VERSION => LOGSTASH_VERSION))
232
+ end
233
+ end
234
+ rescue LogStash::PluginNoVersionError
235
+ # If we cannot find a version in the currently installed gems we
236
+ # will display this message. This could happen in the test, if you
237
+ # create an anonymous class to test a plugin.
238
+ @logger.warn(I18n.t("logstash.plugin.no_version",
239
+ :type => @plugin_type,
240
+ :name => @config_name,
241
+ :LOGSTASH_VERSION => LOGSTASH_VERSION))
242
+ ensure
243
+ @@version_notice_given = true
244
+ end
245
+ end
246
+
247
+ def validate_check_invalid_parameter_names(params)
248
+ invalid_params = params.keys
249
+ # Filter out parameters that match regexp keys.
250
+ # These are defined in plugins like this:
251
+ # config /foo.*/ => ...
252
+ @config.each_key do |config_key|
253
+ if config_key.is_a?(Regexp)
254
+ invalid_params.reject! { |k| k =~ config_key }
255
+ elsif config_key.is_a?(String)
256
+ invalid_params.reject! { |k| k == config_key }
257
+ end
258
+ end
259
+
260
+ if invalid_params.size > 0
261
+ invalid_params.each do |name|
262
+ @logger.error("Unknown setting '#{name}' for #{@plugin_name}")
263
+ end
264
+ return false
265
+ end # if invalid_params.size > 0
266
+ return true
267
+ end # def validate_check_invalid_parameter_names
268
+
269
+ def validate_check_required_parameter_names(params)
270
+ is_valid = true
271
+
272
+ @config.each do |config_key, config|
273
+ next unless config[:required]
274
+
275
+ if config_key.is_a?(Regexp)
276
+ next if params.keys.select { |k| k =~ config_key }.length > 0
277
+ elsif config_key.is_a?(String)
278
+ next if params.keys.member?(config_key)
279
+ end
280
+ @logger.error(I18n.t("logstash.agent.configuration.setting_missing",
281
+ :setting => config_key, :plugin => @plugin_name,
282
+ :type => @plugin_type))
283
+ is_valid = false
284
+ end
285
+
286
+ return is_valid
287
+ end
288
+
289
+ def validate_check_parameter_values(params)
290
+ # Filter out parametrs that match regexp keys.
291
+ # These are defined in plugins like this:
292
+ # config /foo.*/ => ...
293
+ is_valid = true
294
+
295
+ params.each do |key, value|
296
+ @config.keys.each do |config_key|
297
+ next unless (config_key.is_a?(Regexp) && key =~ config_key) \
298
+ || (config_key.is_a?(String) && key == config_key)
299
+ config_val = @config[config_key][:validate]
300
+ #puts " Key matches."
301
+ success, result = validate_value(value, config_val)
302
+ if success
303
+ # Accept coerced value if success
304
+ # Used for converting values in the config to proper objects.
305
+ params[key] = result if !result.nil?
306
+ else
307
+ @logger.error(I18n.t("logstash.agent.configuration.setting_invalid",
308
+ :plugin => @plugin_name, :type => @plugin_type,
309
+ :setting => key, :value => value.inspect,
310
+ :value_type => config_val,
311
+ :note => result))
312
+ end
313
+ #puts "Result: #{key} / #{result.inspect} / #{success}"
314
+ is_valid &&= success
315
+
316
+ break # done with this param key
317
+ end # config.each
318
+ end # params.each
319
+
320
+ return is_valid
321
+ end # def validate_check_parameter_values
322
+
323
+ def validator_find(key)
324
+ @config.each do |config_key, config_val|
325
+ if (config_key.is_a?(Regexp) && key =~ config_key) \
326
+ || (config_key.is_a?(String) && key == config_key)
327
+ return config_val
328
+ end
329
+ end # @config.each
330
+ return nil
331
+ end
332
+
333
+ def validate_value(value, validator)
334
+ # Validator comes from the 'config' pieces of plugins.
335
+ # They look like this
336
+ # config :mykey => lambda do |value| ... end
337
+ # (see LogStash::Inputs::File for example)
338
+ result = nil
339
+
340
+ if validator.nil?
341
+ return true
342
+ elsif validator.is_a?(Array)
343
+ value = [*value]
344
+ if value.size > 1
345
+ return false, "Expected one of #{validator.inspect}, got #{value.inspect}"
346
+ end
347
+
348
+ if !validator.include?(value.first)
349
+ return false, "Expected one of #{validator.inspect}, got #{value.inspect}"
350
+ end
351
+ result = value.first
352
+ elsif validator.is_a?(Symbol)
353
+ # TODO(sissel): Factor this out into a coersion method?
354
+ # TODO(sissel): Document this stuff.
355
+ value = hash_or_array(value)
356
+
357
+ case validator
358
+ when :codec
359
+ if value.first.is_a?(String)
360
+ value = LogStash::Plugin.lookup("codec", value.first).new
361
+ return true, value
362
+ else
363
+ value = value.first
364
+ return true, value
365
+ end
366
+ when :hash
367
+ if value.is_a?(Hash)
368
+ return true, value
369
+ end
370
+
371
+ if value.size % 2 == 1
372
+ return false, "This field must contain an even number of items, got #{value.size}"
373
+ end
374
+
375
+ # Convert the array the config parser produces into a hash.
376
+ result = {}
377
+ value.each_slice(2) do |key, value|
378
+ entry = result[key]
379
+ if entry.nil?
380
+ result[key] = value
381
+ else
382
+ if entry.is_a?(Array)
383
+ entry << value
384
+ else
385
+ result[key] = [entry, value]
386
+ end
387
+ end
388
+ end
389
+ when :array
390
+ result = value
391
+ when :string
392
+ if value.size > 1 # only one value wanted
393
+ return false, "Expected string, got #{value.inspect}"
394
+ end
395
+ result = value.first
396
+ when :number
397
+ if value.size > 1 # only one value wanted
398
+ return false, "Expected number, got #{value.inspect} (type #{value.class})"
399
+ end
400
+
401
+ v = value.first
402
+ case v
403
+ when Numeric
404
+ result = v
405
+ when String
406
+ if v.to_s.to_f.to_s != v.to_s \
407
+ && v.to_s.to_i.to_s != v.to_s
408
+ return false, "Expected number, got #{v.inspect} (type #{v})"
409
+ end
410
+ if v.include?(".")
411
+ # decimal value, use float.
412
+ result = v.to_f
413
+ else
414
+ result = v.to_i
415
+ end
416
+ end # case v
417
+ when :boolean
418
+ if value.size > 1 # only one value wanted
419
+ return false, "Expected boolean, got #{value.inspect}"
420
+ end
421
+
422
+ bool_value = value.first
423
+ if !!bool_value == bool_value
424
+ # is_a does not work for booleans
425
+ # we have Boolean and not a string
426
+ result = bool_value
427
+ else
428
+ if bool_value !~ /^(true|false)$/
429
+ return false, "Expected boolean 'true' or 'false', got #{bool_value.inspect}"
430
+ end
431
+
432
+ result = (bool_value == "true")
433
+ end
434
+ when :ipaddr
435
+ if value.size > 1 # only one value wanted
436
+ return false, "Expected IPaddr, got #{value.inspect}"
437
+ end
438
+
439
+ octets = value.split(".")
440
+ if octets.length != 4
441
+ return false, "Expected IPaddr, got #{value.inspect}"
442
+ end
443
+ octets.each do |o|
444
+ if o.to_i < 0 or o.to_i > 255
445
+ return false, "Expected IPaddr, got #{value.inspect}"
446
+ end
447
+ end
448
+ result = value.first
449
+ when :password
450
+ if value.size > 1
451
+ return false, "Expected password (one value), got #{value.size} values?"
452
+ end
453
+
454
+ result = ::LogStash::Util::Password.new(value.first)
455
+ when :path
456
+ if value.size > 1 # Only 1 value wanted
457
+ return false, "Expected path (one value), got #{value.size} values?"
458
+ end
459
+
460
+ # Paths must be absolute
461
+ #if !Pathname.new(value.first).absolute?
462
+ #return false, "Require absolute path, got relative path #{value.first}?"
463
+ #end
464
+
465
+ if !File.exists?(value.first) # Check if the file exists
466
+ return false, "File does not exist or cannot be opened #{value.first}"
467
+ end
468
+
469
+ result = value.first
470
+ when :bytes
471
+ begin
472
+ bytes = Integer(value.first) rescue nil
473
+ result = bytes || Filesize.from(value.first).to_i
474
+ rescue ArgumentError
475
+ return false, "Unparseable filesize: #{value.first}. possible units (KiB, MiB, ...) e.g. '10 KiB'. doc reference: http://www.elasticsearch.org/guide/en/logstash/current/_logstash_config_language.html#bytes"
476
+ end
477
+ else
478
+ return false, "Unknown validator symbol #{validator}"
479
+ end # case validator
480
+ else
481
+ return false, "Unknown validator #{validator.class}"
482
+ end
483
+
484
+ # Return the validator for later use, like with type coercion.
485
+ return true, result
486
+ end # def validate_value
487
+
488
+ def hash_or_array(value)
489
+ if !value.is_a?(Hash)
490
+ value = [*value] # coerce scalar to array if necessary
491
+ end
492
+ return value
493
+ end
494
+ end # module LogStash::Config::DSL
495
+ end # module LogStash::Config