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,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