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,239 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+ require "logstash/logging"
4
+ require "logstash/plugin"
5
+ require "logstash/config/mixin"
6
+
7
+ class LogStash::Filters::Base < LogStash::Plugin
8
+ include LogStash::Config::Mixin
9
+
10
+ config_name "filter"
11
+
12
+ # Note that all of the specified routing options (`type`,`tags`,`exclude_tags`,`include_fields`,
13
+ # `exclude_fields`) must be met in order for the event to be handled by the filter.
14
+
15
+ # The type to act on. If a type is given, then this filter will only
16
+ # act on messages with the same type. See any input plugin's `type`
17
+ # attribute for more.
18
+ # Optional.
19
+ config :type, :validate => :string, :default => "", :deprecated => "You can achieve this same behavior with the new conditionals, like: `if [type] == \"sometype\" { %PLUGIN% { ... } }`."
20
+
21
+ # Only handle events with all of these tags.
22
+ # Optional.
23
+ config :tags, :validate => :array, :default => [], :deprecated => "You can achieve similar behavior with the new conditionals, like: `if \"sometag\" in [tags] { %PLUGIN% { ... } }`"
24
+
25
+ # Only handle events without any of these tags.
26
+ # Optional.
27
+ config :exclude_tags, :validate => :array, :default => [], :deprecated => "You can achieve similar behavior with the new conditionals, like: `if !(\"sometag\" in [tags]) { %PLUGIN% { ... } }`"
28
+
29
+ # If this filter is successful, add arbitrary tags to the event.
30
+ # Tags can be dynamic and include parts of the event using the `%{field}`
31
+ # syntax.
32
+ #
33
+ # Example:
34
+ # [source,ruby]
35
+ # filter {
36
+ # %PLUGIN% {
37
+ # add_tag => [ "foo_%{somefield}" ]
38
+ # }
39
+ # }
40
+ # [source,ruby]
41
+ # # You can also add multiple tags at once:
42
+ # filter {
43
+ # %PLUGIN% {
44
+ # add_tag => [ "foo_%{somefield}", "taggedy_tag"]
45
+ # }
46
+ # }
47
+ #
48
+ # If the event has field `"somefield" == "hello"` this filter, on success,
49
+ # would add a tag `foo_hello` (and the second example would of course add a `taggedy_tag` tag).
50
+ config :add_tag, :validate => :array, :default => []
51
+
52
+ # If this filter is successful, remove arbitrary tags from the event.
53
+ # Tags can be dynamic and include parts of the event using the `%{field}`
54
+ # syntax.
55
+ #
56
+ # Example:
57
+ # [source,ruby]
58
+ # filter {
59
+ # %PLUGIN% {
60
+ # remove_tag => [ "foo_%{somefield}" ]
61
+ # }
62
+ # }
63
+ # [source,ruby]
64
+ # # You can also remove multiple tags at once:
65
+ # filter {
66
+ # %PLUGIN% {
67
+ # remove_tag => [ "foo_%{somefield}", "sad_unwanted_tag"]
68
+ # }
69
+ # }
70
+ #
71
+ # If the event has field `"somefield" == "hello"` this filter, on success,
72
+ # would remove the tag `foo_hello` if it is present. The second example
73
+ # would remove a sad, unwanted tag as well.
74
+ config :remove_tag, :validate => :array, :default => []
75
+
76
+ # If this filter is successful, add any arbitrary fields to this event.
77
+ # Field names can be dynamic and include parts of the event using the `%{field}`.
78
+ #
79
+ # Example:
80
+ # [source,ruby]
81
+ # filter {
82
+ # %PLUGIN% {
83
+ # add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
84
+ # }
85
+ # }
86
+ # [source,ruby]
87
+ # # You can also add multiple fields at once:
88
+ # filter {
89
+ # %PLUGIN% {
90
+ # add_field => {
91
+ # "foo_%{somefield}" => "Hello world, from %{host}"
92
+ # "new_field" => "new_static_value"
93
+ # }
94
+ # }
95
+ # }
96
+ #
97
+ # If the event has field `"somefield" == "hello"` this filter, on success,
98
+ # would add field `foo_hello` if it is present, with the
99
+ # value above and the `%{host}` piece replaced with that value from the
100
+ # event. The second example would also add a hardcoded field.
101
+ config :add_field, :validate => :hash, :default => {}
102
+
103
+ # If this filter is successful, remove arbitrary fields from this event.
104
+ # Fields names can be dynamic and include parts of the event using the %{field}
105
+ # Example:
106
+ # [source,ruby]
107
+ # filter {
108
+ # %PLUGIN% {
109
+ # remove_field => [ "foo_%{somefield}" ]
110
+ # }
111
+ # }
112
+ # [source,ruby]
113
+ # # You can also remove multiple fields at once:
114
+ # filter {
115
+ # %PLUGIN% {
116
+ # remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
117
+ # }
118
+ # }
119
+ #
120
+ # If the event has field `"somefield" == "hello"` this filter, on success,
121
+ # would remove the field with name `foo_hello` if it is present. The second
122
+ # example would remove an additional, non-dynamic field.
123
+ config :remove_field, :validate => :array, :default => []
124
+
125
+ # Call the filter flush method at regular interval.
126
+ # Optional.
127
+ config :periodic_flush, :validate => :boolean, :default => false
128
+
129
+ RESERVED = ["type", "tags", "exclude_tags", "include_fields", "exclude_fields", "add_tag", "remove_tag", "add_field", "remove_field", "include_any", "exclude_any"]
130
+
131
+ public
132
+ def initialize(params)
133
+ super
134
+ config_init(params)
135
+ @threadsafe = true
136
+ end # def initialize
137
+
138
+ public
139
+ def register
140
+ raise "#{self.class}#register must be overidden"
141
+ end # def register
142
+
143
+ public
144
+ def filter(event)
145
+ raise "#{self.class}#filter must be overidden"
146
+ end # def filter
147
+
148
+ public
149
+ def execute(event, &block)
150
+ filter(event, &block)
151
+ end # def execute
152
+
153
+ public
154
+ def threadsafe?
155
+ @threadsafe
156
+ end
157
+
158
+ # a filter instance should call filter_matched from filter if the event
159
+ # matches the filter's conditions (right type, etc)
160
+ protected
161
+ def filter_matched(event)
162
+ @add_field.each do |field, value|
163
+ field = event.sprintf(field)
164
+ value = [value] if !value.is_a?(Array)
165
+ value.each do |v|
166
+ v = event.sprintf(v)
167
+ if event.include?(field)
168
+ event[field] = [event[field]] if !event[field].is_a?(Array)
169
+ event[field] << v
170
+ else
171
+ event[field] = v
172
+ end
173
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: adding value to field",
174
+ :field => field, :value => value)
175
+ end
176
+ end
177
+
178
+ @remove_field.each do |field|
179
+ field = event.sprintf(field)
180
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: removing field",
181
+ :field => field)
182
+ event.remove(field)
183
+ end
184
+
185
+ @add_tag.each do |tag|
186
+ tag = event.sprintf(tag)
187
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: adding tag",
188
+ :tag => tag)
189
+ (event["tags"] ||= []) << tag
190
+ end
191
+
192
+ @remove_tag.each do |tag|
193
+ break if event["tags"].nil?
194
+ tag = event.sprintf(tag)
195
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: removing tag",
196
+ :tag => tag)
197
+ event["tags"].delete(tag)
198
+ end
199
+ end # def filter_matched
200
+
201
+ protected
202
+ def filter?(event)
203
+ if !@type.empty?
204
+ if event["type"] != @type
205
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: Skipping event because type doesn't match",
206
+ :type=> @type, :event => event)
207
+ return false
208
+ end
209
+ end
210
+
211
+ if !@tags.empty?
212
+ # this filter has only works on events with certain tags,
213
+ # and this event has no tags.
214
+ return false if !event["tags"]
215
+
216
+ # Is @tags a subset of the event's tags? If not, skip it.
217
+ if (event["tags"] & @tags).size != @tags.size
218
+ @logger.debug? and @logger.debug("filters/#{self.class.name}: Skipping event because tags don't match",
219
+ :tags => tags, :event => event)
220
+ return false
221
+ end
222
+ end
223
+
224
+ if !@exclude_tags.empty? && event["tags"]
225
+ if (diff_tags = (event["tags"] & @exclude_tags)).size != 0
226
+ @logger.debug("filters/#{self.class.name}: Skipping event because tags contains excluded tags:",
227
+ :diff_tags => diff_tags, :exclude_tags => @exclude_tags, :event => event)
228
+ return false
229
+ end
230
+ end
231
+
232
+ return true
233
+ end
234
+
235
+ public
236
+ def teardown
237
+ # Nothing to do by default.
238
+ end
239
+ end # class LogStash::Filters::Base
@@ -0,0 +1,175 @@
1
+ module LogStash
2
+
3
+ class GemfileError < StandardError; end
4
+
5
+ class Gemfile
6
+ attr_accessor :gemset
7
+
8
+ HEADER = \
9
+ "# This is a Logstash generated Gemfile.\n" + \
10
+ "# If you modify this file manually all comments and formatting will be lost.\n\n"
11
+
12
+ # @params io [IO] any IO object that supports read, write, truncate, rewind
13
+ def initialize(io)
14
+ @io = io
15
+ @gemset = nil
16
+ end
17
+
18
+ def load
19
+ @gemset ||= DSL.parse(@io.read)
20
+ self
21
+ end
22
+
23
+ def save
24
+ raise(GemfileError, "a Gemfile must first be loaded") unless @gemset
25
+ @io.truncate(0)
26
+ @io.rewind
27
+ @io.write(HEADER)
28
+ @io.write(@gemset.to_s)
29
+ @io.flush
30
+ end
31
+
32
+ def find(name)
33
+ @gemset.find_gem(name)
34
+ end
35
+
36
+ # @param name [String] gem name
37
+ # @param *requirements params following name use the same notation as the Gemfile gem DSL statement
38
+ # @raise GemfileError if gem already exists in Gemfile
39
+ def add(name, *requirements)
40
+ @gemset.add_gem(Gem.parse(name, *requirements))
41
+ end
42
+
43
+ # update existing or add new
44
+ # @param name [String] gem name
45
+ # @param *requirements params following name use the same notation as the Gemfile gem DSL statement
46
+ def update(name, *requirements)
47
+ @gemset.update_gem(Gem.parse(name, *requirements))
48
+ end
49
+
50
+ # @return [Gem] removed gem or nil if not found
51
+ def remove(name)
52
+ @gemset.remove_gem(name)
53
+ end
54
+ end
55
+
56
+ class Gemset
57
+ attr_accessor :sources, :gems, :gemspec
58
+
59
+ def initialize
60
+ @sources = [] # list of urls
61
+ @gems = [] # list of Gem class
62
+ @gems_by_name = {} # hash of name => Gem
63
+ @gemspec = {} # gemspec is a options hash
64
+ end
65
+
66
+ def to_s
67
+ [sources_to_s, gemspec_to_s, gems_to_s].select{|s| !s.empty?}.join("\n") + "\n"
68
+ end
69
+
70
+ # @return [Gem] found gem or nil if not found
71
+ def find_gem(name)
72
+ @gems_by_name[name.downcase]
73
+ end
74
+
75
+ # @raise GemfileError if gem already exists
76
+ def add_gem(_gem)
77
+ raise(GemfileError, "duplicate gem #{_gem.name}") if find_gem(_gem.name)
78
+ @gems << _gem
79
+ @gems_by_name[_gem.name.downcase] = _gem
80
+ end
81
+
82
+ # update existing or add new
83
+ def update_gem(_gem)
84
+ if old = find_gem(_gem.name)
85
+ @gems[@gems.index(old)] = _gem
86
+ else
87
+ @gems << _gem
88
+ end
89
+ @gems_by_name[_gem.name.downcase] = _gem
90
+ end
91
+
92
+ # @return [Gem] removed gem or nil if not found
93
+ def remove_gem(name)
94
+ if _gem = @gems_by_name.delete(name.downcase)
95
+ @gems.delete_at(@gems.index(_gem))
96
+ end
97
+ _gem
98
+ end
99
+
100
+ # deep clone self
101
+ def copy
102
+ Marshal.load(Marshal.dump(self))
103
+ end
104
+
105
+ private
106
+
107
+ def sources_to_s
108
+ return "" if @sources.empty?
109
+ @sources.map{|source| "source #{source.inspect}"}.join("\n")
110
+ end
111
+
112
+ def gems_to_s
113
+ return "" if @gems.empty?
114
+ @gems.map do |gem|
115
+ requirements = gem.requirements.empty? ? nil : gem.requirements.map{|r| r.inspect}.join(", ")
116
+ options = gem.options.empty? ? nil : gem.options.map{|k, v| "#{k.inspect} => #{v.inspect}"}.join(", ")
117
+ "gem " + [gem.name.inspect, requirements, options].compact.join(", ")
118
+ end.join("\n")
119
+ end
120
+
121
+ def gemspec_to_s
122
+ return "" if @gemspec.empty?
123
+ options = @gemspec.map{|k, v| "#{k.inspect} => #{v.inspect}"}.join(", ")
124
+ "gemspec #{options}"
125
+ end
126
+ end
127
+
128
+ # DSL is a minimal, incomplete Gemfile DSL subset parser, only what is currently required is implemented.
129
+ class DSL
130
+ attr_reader :gemset
131
+
132
+ def initialize
133
+ @gemset = Gemset.new
134
+ end
135
+
136
+ # @param gemfile_content [String] the Gemfile string content
137
+ # @return [Gemset] parsed Gemfile content as a Gemset
138
+ def self.parse(gemfile_content)
139
+ dsl = self.new
140
+ dsl.instance_eval(gemfile_content)
141
+ dsl.gemset
142
+ end
143
+
144
+ # DSL methods
145
+
146
+ def source(url)
147
+ @gemset.sources << url
148
+ end
149
+
150
+ def gem(name, *requirements)
151
+ parsed = Gem.parse(name, *requirements)
152
+ @gemset.add_gem(parsed)
153
+ end
154
+
155
+ def gemspec(options = {})
156
+ raise(GemfileError, "cannot declare multiple gemspec directives") unless @gemset.gemspec.empty?
157
+ @gemset.gemspec = options
158
+ end
159
+ end
160
+
161
+ class Gem
162
+ attr_accessor :name, :requirements, :options
163
+
164
+ def initialize(name, requirements = [], options = {})
165
+ @name = name
166
+ @requirements = requirements.map{|r| r.to_s.strip}.select{|r| !r.empty?}
167
+ @options = options
168
+ end
169
+
170
+ def self.parse(name, *requirements)
171
+ options = requirements.last.is_a?(Hash) ? requirements.pop : {}
172
+ self.new(name, requirements, options)
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,137 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+ require "logstash/event"
4
+ require "logstash/plugin"
5
+ require "logstash/logging"
6
+ require "logstash/config/mixin"
7
+ require "logstash/codecs/base"
8
+
9
+ # This is the base class for Logstash inputs.
10
+ class LogStash::Inputs::Base < LogStash::Plugin
11
+ include LogStash::Config::Mixin
12
+ config_name "input"
13
+
14
+ # Add a `type` field to all events handled by this input.
15
+ #
16
+ # Types are used mainly for filter activation.
17
+ #
18
+ # The type is stored as part of the event itself, so you can
19
+ # also use the type to search for it in Kibana.
20
+ #
21
+ # If you try to set a type on an event that already has one (for
22
+ # example when you send an event from a shipper to an indexer) then
23
+ # a new input will not override the existing type. A type set at
24
+ # the shipper stays with that event for its life even
25
+ # when sent to another Logstash server.
26
+ config :type, :validate => :string
27
+
28
+ config :debug, :validate => :boolean, :default => false, :deprecated => "This setting no longer has any effect. In past releases, it existed, but almost no plugin made use of it."
29
+
30
+ # The format of input data (plain, json, json_event)
31
+ config :format, :validate => ["plain", "json", "json_event", "msgpack_event"], :deprecated => "You should use the newer 'codec' setting instead."
32
+
33
+ # The codec used for input data. Input codecs are a convenient method for decoding your data before it enters the input, without needing a separate filter in your Logstash pipeline.
34
+ config :codec, :validate => :codec, :default => "plain"
35
+
36
+ # The character encoding used in this input. Examples include `UTF-8`
37
+ # and `cp1252`
38
+ #
39
+ # This setting is useful if your log files are in `Latin-1` (aka `cp1252`)
40
+ # or in another character set other than `UTF-8`.
41
+ #
42
+ # This only affects `plain` format logs since json is `UTF-8` already.
43
+ config :charset, :validate => ::Encoding.name_list, :deprecated => true
44
+
45
+ # If format is `json`, an event `sprintf` string to build what
46
+ # the display `@message` should be given (defaults to the raw JSON).
47
+ # `sprintf` format strings look like `%{fieldname}`
48
+ #
49
+ # If format is `json_event`, ALL fields except for `@type`
50
+ # are expected to be present. Not receiving all fields
51
+ # will cause unexpected results.
52
+ config :message_format, :validate => :string, :deprecated => true
53
+
54
+ # Add any number of arbitrary tags to your event.
55
+ #
56
+ # This can help with processing later.
57
+ config :tags, :validate => :array
58
+
59
+ # Add a field to an event
60
+ config :add_field, :validate => :hash, :default => {}
61
+
62
+ attr_accessor :params
63
+ attr_accessor :threadable
64
+
65
+ public
66
+ def initialize(params={})
67
+ super
68
+ @threadable = false
69
+ config_init(params)
70
+ @tags ||= []
71
+
72
+ if @charset && @codec.class.get_config.include?("charset")
73
+ # charset is deprecated on inputs, but provide backwards compatibility
74
+ # by copying the charset setting into the codec.
75
+
76
+ @logger.info("Copying input's charset setting into codec", :input => self, :codec => @codec)
77
+ charset = @charset
78
+ @codec.instance_eval { @charset = charset }
79
+ end
80
+
81
+ # Backwards compat for the 'format' setting
82
+ case @format
83
+ when "plain"; # do nothing
84
+ when "json"
85
+ @codec = LogStash::Plugin.lookup("codec", "json").new
86
+ when "json_event"
87
+ @codec = LogStash::Plugin.lookup("codec", "oldlogstashjson").new
88
+ end
89
+
90
+ end # def initialize
91
+
92
+ public
93
+ def register
94
+ raise "#{self.class}#register must be overidden"
95
+ end # def register
96
+
97
+ public
98
+ def tag(newtag)
99
+ @tags << newtag
100
+ end # def tag
101
+
102
+ protected
103
+ def to_event(raw, source)
104
+ raise LogStash::ThisMethodWasRemoved("LogStash::Inputs::Base#to_event - you should use codecs now instead of to_event. Not sure what this means? Get help on logstash-users@googlegroups.com!")
105
+ end # def to_event
106
+
107
+ protected
108
+ def decorate(event)
109
+ # Only set 'type' if not already set. This is backwards-compatible behavior
110
+ event["type"] = @type if @type && !event.include?("type")
111
+
112
+ if @tags.any?
113
+ event["tags"] ||= []
114
+ event["tags"] += @tags
115
+ end
116
+
117
+ @add_field.each do |field, value|
118
+ event[field] = value
119
+ end
120
+ end
121
+
122
+ protected
123
+ def fix_streaming_codecs
124
+ require "logstash/codecs/plain"
125
+ require "logstash/codecs/line"
126
+ require "logstash/codecs/json"
127
+ require "logstash/codecs/json_lines"
128
+ case @codec
129
+ when LogStash::Codecs::Plain
130
+ @logger.info("Automatically switching from #{@codec.class.config_name} to line codec", :plugin => self.class.config_name)
131
+ @codec = LogStash::Codecs::Line.new("charset" => @codec.charset)
132
+ when LogStash::Codecs::JSON
133
+ @logger.info("Automatically switching from #{@codec.class.config_name} to json_lines codec", :plugin => self.class.config_name)
134
+ @codec = LogStash::Codecs::JSONLines.new("charset" => @codec.charset)
135
+ end
136
+ end
137
+ end # class LogStash::Inputs::Base