logstash-core 1.5.0.beta2-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.

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,13 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+
4
+ # Global config registry.
5
+ module LogStash::Config::Registry
6
+ @registry = Hash.new
7
+ class << self
8
+ attr_accessor :registry
9
+
10
+ # TODO(sissel): Add some helper methods here.
11
+ end
12
+ end # module LogStash::Config::Registry
13
+
@@ -0,0 +1,168 @@
1
+ require "logstash/errors"
2
+ require 'logstash/version'
3
+
4
+ # monkey patch RubyGems to silence ffi warnings:
5
+ #
6
+ # WARN: Unresolved specs during Gem::Specification.reset:
7
+ # ffi (>= 0)
8
+ # WARN: Clearing out unresolved specs.
9
+ # Please report a bug if this causes problems.
10
+ #
11
+ # see https://github.com/elasticsearch/logstash/issues/2556 and https://github.com/rubygems/rubygems/issues/1070
12
+ #
13
+ # this code is from Rubygems v2.1.9 in JRuby 1.7.17. Per tickets this issue should be solved at JRuby >= 1.7.20.
14
+
15
+ # this method implementation works for Rubygems version 2.1.0 and up, verified up to 2.4.6
16
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.1.0") && Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.5.0")
17
+ class Gem::Specification
18
+ def self.reset
19
+ @@dirs = nil
20
+ Gem.pre_reset_hooks.each { |hook| hook.call }
21
+ @@all = nil
22
+ @@stubs = nil
23
+ _clear_load_cache
24
+ unresolved = unresolved_deps
25
+ unless unresolved.empty?
26
+ unless (unresolved.size == 1 && unresolved["ffi"])
27
+ w = "W" + "ARN"
28
+ warn "#{w}: Unresolved specs during Gem::Specification.reset:"
29
+ unresolved.values.each do |dep|
30
+ warn " #{dep}"
31
+ end
32
+ warn "#{w}: Clearing out unresolved specs."
33
+ warn "Please report a bug if this causes problems."
34
+ end
35
+ unresolved.clear
36
+ end
37
+ Gem.post_reset_hooks.each { |hook| hook.call }
38
+ end
39
+ end
40
+ end
41
+
42
+ module LogStash
43
+ module Environment
44
+ extend self
45
+
46
+ LOGSTASH_HOME = ::File.expand_path(::File.join(::File.dirname(__FILE__), "..", ".."))
47
+ JAR_DIR = ::File.join(LOGSTASH_HOME, "vendor", "jar")
48
+ ELASTICSEARCH_DIR = ::File.join(LOGSTASH_HOME, "vendor", "elasticsearch")
49
+ BUNDLE_DIR = ::File.join(LOGSTASH_HOME, "vendor", "bundle")
50
+ GEMFILE_PATH = ::File.join(LOGSTASH_HOME, "Gemfile")
51
+ BUNDLE_CONFIG_PATH = ::File.join(LOGSTASH_HOME, ".bundle", "config")
52
+ BOOTSTRAP_GEM_PATH = ::File.join(LOGSTASH_HOME, 'build', 'bootstrap')
53
+
54
+ LOGSTASH_ENV = (ENV["LS_ENV"] || 'production').to_s.freeze
55
+
56
+ # loads currently embedded elasticsearch jars
57
+ # @raise LogStash::EnvironmentError if not running under JRuby or if no jar files are found
58
+ def load_elasticsearch_jars!
59
+ raise(LogStash::EnvironmentError, "JRuby is required") unless jruby?
60
+
61
+ require "java"
62
+ jars_path = ::File.join(ELASTICSEARCH_DIR, "**", "*.jar")
63
+ jar_files = Dir.glob(jars_path)
64
+
65
+ raise(LogStash::EnvironmentError, "Could not find Elasticsearch jar files under #{ELASTICSEARCH_DIR}") if jar_files.empty?
66
+
67
+ jar_files.each do |jar|
68
+ loaded = require jar
69
+ puts("Loaded #{jar}") if $DEBUG && loaded
70
+ end
71
+ end
72
+
73
+ def logstash_gem_home
74
+ ::File.join(BUNDLE_DIR, ruby_engine, gem_ruby_version)
75
+ end
76
+
77
+ def env
78
+ LOGSTASH_ENV
79
+ end
80
+
81
+ def production?
82
+ env.downcase == "production"
83
+ end
84
+
85
+ def development?
86
+ env.downcase == "development"
87
+ end
88
+
89
+ def test?
90
+ env.downcase == "test"
91
+ end
92
+
93
+ def bundler_setup!
94
+ # if there's no .bundle/config setup the runtime environment.
95
+ unless ::File.exists?(BUNDLE_CONFIG_PATH)
96
+ ENV["BUNDLE_PATH"] = LogStash::Environment::BUNDLE_DIR
97
+ ENV["BUNDLE_WITHOUT"] = "development"
98
+ end
99
+ # force BUNDLE_GEMFILE since Bundler does not store it in its ./bundle/config. this is required otherwise Bundler will look for the Gemfile in the CWD
100
+ # and will crash when invoking logstash outside its home dir.
101
+ ENV["BUNDLE_GEMFILE"] = LogStash::Environment::GEMFILE_PATH
102
+
103
+ # make sure we use our own nicely installed bundler and not a rogue, bad, mean, ugly, stupid other bundler. bad bundler, bad bad bundler go away.
104
+ Gem.clear_paths
105
+ Gem.paths = ENV['GEM_HOME'] = ENV['GEM_PATH'] = logstash_gem_home
106
+ require "bundler"
107
+
108
+ require "logstash/bundler"
109
+
110
+ ::Bundler.reset_settings # our monkey patched method
111
+ ::Bundler.reset!
112
+ ::Bundler.setup
113
+ end
114
+
115
+ def ruby_bin
116
+ ENV["USE_RUBY"] == "1" ? "ruby" : File.join("vendor", "jruby", "bin", "jruby")
117
+ end
118
+
119
+ # @return [String] major.minor ruby version, ex 1.9
120
+ def ruby_abi_version
121
+ RUBY_VERSION[/(\d+\.\d+)(\.\d+)*/, 1]
122
+ end
123
+
124
+ # @return [String] the ruby version string bundler uses to craft its gem path
125
+ def gem_ruby_version
126
+ RbConfig::CONFIG["ruby_version"]
127
+ end
128
+
129
+ # @return [String] jruby, ruby, rbx, ...
130
+ def ruby_engine
131
+ RUBY_ENGINE
132
+ end
133
+
134
+ def jruby?
135
+ @jruby ||= !!(RUBY_PLATFORM == "java")
136
+ end
137
+
138
+ def windows?
139
+ Gem.win_platform?
140
+ end
141
+
142
+ def vendor_path(path)
143
+ return ::File.join(LOGSTASH_HOME, "vendor", path)
144
+ end
145
+
146
+ def plugin_path(path)
147
+ return ::File.join(LOGSTASH_HOME, "lib", "logstash", path)
148
+ end
149
+
150
+ def pattern_path(path)
151
+ return ::File.join(LOGSTASH_HOME, "patterns", path)
152
+ end
153
+
154
+ def locales_path(path)
155
+ return ::File.join(LOGSTASH_HOME, "locales", path)
156
+ end
157
+
158
+ def load_locale!
159
+ require "i18n"
160
+ I18n.enforce_available_locales = true
161
+ I18n.load_path << LogStash::Environment.locales_path("en.yml")
162
+ I18n.reload!
163
+ fail "No locale? This is a bug." if I18n.available_locales.empty?
164
+ end
165
+ end
166
+ end
167
+
168
+ require "logstash/patches"
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ module LogStash
3
+ class Error < ::StandardError; end
4
+ class EnvironmentError < Error; end
5
+ class ConfigurationError < Error; end
6
+ class PluginLoadingError < Error; end
7
+ class ShutdownSignal < StandardError; end
8
+ class PluginNoVersionError < Error; end
9
+
10
+ class Bug < Error; end
11
+ class ThisMethodWasRemoved < Bug; end
12
+ end
@@ -0,0 +1,310 @@
1
+ # encoding: utf-8
2
+ require "time"
3
+ require "date"
4
+ require "cabin"
5
+ require "logstash/namespace"
6
+ require "logstash/util/fieldreference"
7
+ require "logstash/util/accessors"
8
+ require "logstash/timestamp"
9
+ require "logstash/json"
10
+
11
+ # transcient pipeline events for normal in-flow signaling as opposed to
12
+ # flow altering exceptions. for now having base classes is adequate and
13
+ # in the future it might be necessary to refactor using like a BaseEvent
14
+ # class to have a common interface for all pileline events to support
15
+ # eventual queueing persistence for example, TBD.
16
+ class LogStash::ShutdownEvent; end
17
+ class LogStash::FlushEvent; end
18
+
19
+ # the logstash event object.
20
+ #
21
+ # An event is simply a tuple of (timestamp, data).
22
+ # The 'timestamp' is an ISO8601 timestamp. Data is anything - any message,
23
+ # context, references, etc that are relevant to this event.
24
+ #
25
+ # Internally, this is represented as a hash with only two guaranteed fields.
26
+ #
27
+ # * "@timestamp" - an ISO8601 timestamp representing the time the event
28
+ # occurred at.
29
+ # * "@version" - the version of the schema. Currently "1"
30
+ #
31
+ # They are prefixed with an "@" symbol to avoid clashing with your
32
+ # own custom fields.
33
+ #
34
+ # When serialized, this is represented in JSON. For example:
35
+ #
36
+ # {
37
+ # "@timestamp": "2013-02-09T20:39:26.234Z",
38
+ # "@version": "1",
39
+ # message: "hello world"
40
+ # }
41
+ class LogStash::Event
42
+ class DeprecatedMethod < StandardError; end
43
+
44
+ CHAR_PLUS = "+"
45
+ TIMESTAMP = "@timestamp"
46
+ VERSION = "@version"
47
+ VERSION_ONE = "1"
48
+ TIMESTAMP_FAILURE_TAG = "_timestampparsefailure"
49
+ TIMESTAMP_FAILURE_FIELD = "_@timestamp"
50
+
51
+ # Floats outside of these upper and lower bounds are forcibly converted
52
+ # to scientific notation by Float#to_s
53
+ MIN_FLOAT_BEFORE_SCI_NOT = 0.0001
54
+ MAX_FLOAT_BEFORE_SCI_NOT = 1000000000000000.0
55
+
56
+ public
57
+ def initialize(data = {})
58
+ @logger = Cabin::Channel.get(LogStash)
59
+ @cancelled = false
60
+ @data = data
61
+ @accessors = LogStash::Util::Accessors.new(data)
62
+ @data[VERSION] ||= VERSION_ONE
63
+ @data[TIMESTAMP] = init_timestamp(@data[TIMESTAMP])
64
+
65
+ @metadata = if @data.include?("@metadata")
66
+ @data.delete("@metadata")
67
+ else
68
+ {}
69
+ end
70
+ @metadata_accessors = LogStash::Util::Accessors.new(@metadata)
71
+ end # def initialize
72
+
73
+ public
74
+ def cancel
75
+ @cancelled = true
76
+ end # def cancel
77
+
78
+ public
79
+ def uncancel
80
+ @cancelled = false
81
+ end # def uncancel
82
+
83
+ public
84
+ def cancelled?
85
+ return @cancelled
86
+ end # def cancelled?
87
+
88
+ # Create a deep-ish copy of this event.
89
+ public
90
+ def clone
91
+ copy = {}
92
+ @data.each do |k,v|
93
+ # TODO(sissel): Recurse if this is a hash/array?
94
+ copy[k] = begin v.clone rescue v end
95
+ end
96
+ return self.class.new(copy)
97
+ end # def clone
98
+
99
+ public
100
+ def to_s
101
+ self.sprintf("#{timestamp.to_iso8601} %{host} %{message}")
102
+ end # def to_s
103
+
104
+ public
105
+ def timestamp; return @data[TIMESTAMP]; end # def timestamp
106
+ def timestamp=(val); return @data[TIMESTAMP] = val; end # def timestamp=
107
+
108
+ def unix_timestamp
109
+ raise DeprecatedMethod
110
+ end # def unix_timestamp
111
+
112
+ def ruby_timestamp
113
+ raise DeprecatedMethod
114
+ end # def unix_timestamp
115
+
116
+ # field-related access
117
+ METADATA = "@metadata".freeze
118
+ METADATA_BRACKETS = "[#{METADATA}]".freeze
119
+ public
120
+ def [](fieldref)
121
+ if fieldref.start_with?(METADATA_BRACKETS)
122
+ @metadata_accessors.get(fieldref[METADATA_BRACKETS.length .. -1])
123
+ elsif fieldref == METADATA
124
+ @metadata
125
+ else
126
+ @accessors.get(fieldref)
127
+ end
128
+ end # def []
129
+
130
+ public
131
+ def []=(fieldref, value)
132
+ if fieldref == TIMESTAMP && !value.is_a?(LogStash::Timestamp)
133
+ raise TypeError, "The field '@timestamp' must be a (LogStash::Timestamp, not a #{value.class} (#{value})"
134
+ end
135
+ if fieldref.start_with?(METADATA_BRACKETS)
136
+ @metadata_accessors.set(fieldref[METADATA_BRACKETS.length .. -1], value)
137
+ elsif fieldref == METADATA
138
+ @metadata = value
139
+ else
140
+ @accessors.set(fieldref, value)
141
+ end
142
+ end # def []=
143
+
144
+ public
145
+ def fields
146
+ raise DeprecatedMethod
147
+ end
148
+
149
+ public
150
+ def to_json(*args)
151
+ # ignore arguments to respect accepted to_json method signature
152
+ LogStash::Json.dump(@data)
153
+ end # def to_json
154
+
155
+ public
156
+ def to_hash
157
+ @data
158
+ end # def to_hash
159
+
160
+ public
161
+ def overwrite(event)
162
+ # pickup new event @data and also pickup @accessors
163
+ # otherwise it will be pointing on previous data
164
+ @data = event.instance_variable_get(:@data)
165
+ @accessors = event.instance_variable_get(:@accessors)
166
+
167
+ #convert timestamp if it is a String
168
+ if @data[TIMESTAMP].is_a?(String)
169
+ @data[TIMESTAMP] = LogStash::Timestamp.parse_iso8601(@data[TIMESTAMP])
170
+ end
171
+ end
172
+
173
+ public
174
+ def include?(key)
175
+ return !self[key].nil?
176
+ end # def include?
177
+
178
+ # Append an event to this one.
179
+ public
180
+ def append(event)
181
+ # non-destructively merge that event with ourselves.
182
+
183
+ # no need to reset @accessors here because merging will not disrupt any existing field paths
184
+ # and if new ones are created they will be picked up.
185
+ LogStash::Util.hash_merge(@data, event.to_hash)
186
+ end # append
187
+
188
+ # Remove a field or field reference. Returns the value of that field when
189
+ # deleted
190
+ public
191
+ def remove(fieldref)
192
+ @accessors.del(fieldref)
193
+ end # def remove
194
+
195
+ # sprintf. This could use a better method name.
196
+ # The idea is to take an event and convert it to a string based on
197
+ # any format values, delimited by %{foo} where 'foo' is a field or
198
+ # metadata member.
199
+ #
200
+ # For example, if the event has type == "foo" and host == "bar"
201
+ # then this string:
202
+ # "type is %{type} and source is %{host}"
203
+ # will return
204
+ # "type is foo and source is bar"
205
+ #
206
+ # If a %{name} value is an array, then we will join by ','
207
+ # If a %{name} value does not exist, then no substitution occurs.
208
+ #
209
+ # TODO(sissel): It is not clear what the value of a field that
210
+ # is an array (or hash?) should be. Join by comma? Something else?
211
+ public
212
+ def sprintf(format)
213
+ if format.is_a?(Float) and
214
+ (format < MIN_FLOAT_BEFORE_SCI_NOT or format >= MAX_FLOAT_BEFORE_SCI_NOT) then
215
+ format = ("%.15f" % format).sub(/0*$/,"")
216
+ else
217
+ format = format.to_s
218
+ end
219
+ if format.index("%").nil?
220
+ return format
221
+ end
222
+
223
+ return format.gsub(/%\{[^}]+\}/) do |tok|
224
+ # Take the inside of the %{ ... }
225
+ key = tok[2 ... -1]
226
+
227
+ if key == "+%s"
228
+ # Got %{+%s}, support for unix epoch time
229
+ next @data[TIMESTAMP].to_i
230
+ elsif key[0,1] == "+"
231
+ t = @data[TIMESTAMP]
232
+ formatter = org.joda.time.format.DateTimeFormat.forPattern(key[1 .. -1])\
233
+ .withZone(org.joda.time.DateTimeZone::UTC)
234
+ #next org.joda.time.Instant.new(t.tv_sec * 1000 + t.tv_usec / 1000).toDateTime.toString(formatter)
235
+ # Invoke a specific Instant constructor to avoid this warning in JRuby
236
+ # > ambiguous Java methods found, using org.joda.time.Instant(long)
237
+ org.joda.time.Instant.java_class.constructor(Java::long).new_instance(
238
+ t.tv_sec * 1000 + t.tv_usec / 1000
239
+ ).to_java.toDateTime.toString(formatter)
240
+ else
241
+ value = self[key]
242
+ case value
243
+ when nil
244
+ tok # leave the %{foo} if this field does not exist in this event.
245
+ when Array
246
+ value.join(",") # Join by ',' if value is an array
247
+ when Hash
248
+ LogStash::Json.dump(value) # Convert hashes to json
249
+ else
250
+ value # otherwise return the value
251
+ end # case value
252
+ end # 'key' checking
253
+ end # format.gsub...
254
+ end # def sprintf
255
+
256
+ def tag(value)
257
+ # Generalize this method for more usability
258
+ self["tags"] ||= []
259
+ self["tags"] << value unless self["tags"].include?(value)
260
+ end
261
+
262
+ private
263
+
264
+ def init_timestamp(o)
265
+ begin
266
+ timestamp = o ? LogStash::Timestamp.coerce(o) : LogStash::Timestamp.now
267
+ return timestamp if timestamp
268
+
269
+ @logger.warn("Unrecognized #{TIMESTAMP} value, setting current time to #{TIMESTAMP}, original in #{TIMESTAMP_FAILURE_FIELD}field", :value => o.inspect)
270
+ rescue LogStash::TimestampParserError => e
271
+ @logger.warn("Error parsing #{TIMESTAMP} string, setting current time to #{TIMESTAMP}, original in #{TIMESTAMP_FAILURE_FIELD} field", :value => o.inspect, :exception => e.message)
272
+ end
273
+
274
+ @data["tags"] ||= []
275
+ @data["tags"] << TIMESTAMP_FAILURE_TAG unless @data["tags"].include?(TIMESTAMP_FAILURE_TAG)
276
+ @data[TIMESTAMP_FAILURE_FIELD] = o
277
+
278
+ LogStash::Timestamp.now
279
+ end
280
+
281
+ public
282
+ def to_hash_with_metadata
283
+ if @metadata.nil?
284
+ to_hash
285
+ else
286
+ to_hash.merge("@metadata" => @metadata)
287
+ end
288
+ end
289
+
290
+ public
291
+ def to_json_with_metadata(*args)
292
+ # ignore arguments to respect accepted to_json method signature
293
+ LogStash::Json.dump(to_hash_with_metadata)
294
+ end # def to_json
295
+
296
+ def self.validate_value(value)
297
+ case value
298
+ when String
299
+ raise("expected UTF-8 encoding for value=#{value}, encoding=#{value.encoding.inspect}") unless value.encoding == Encoding::UTF_8
300
+ raise("invalid UTF-8 encoding for value=#{value}, encoding=#{value.encoding.inspect}") unless value.valid_encoding?
301
+ value
302
+ when Array
303
+ value.each{|v| validate_value(v)} # don't map, return original object
304
+ value
305
+ else
306
+ value
307
+ end
308
+ end
309
+
310
+ end # class LogStash::Event