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.
- checksums.yaml +7 -0
- data/lib/logstash-event.rb +2 -0
- data/lib/logstash.rb +4 -0
- data/lib/logstash/JRUBY-PR1448.rb +32 -0
- data/lib/logstash/agent.rb +355 -0
- data/lib/logstash/bundler.rb +124 -0
- data/lib/logstash/codecs/base.rb +50 -0
- data/lib/logstash/config/config_ast.rb +508 -0
- data/lib/logstash/config/file.rb +39 -0
- data/lib/logstash/config/grammar.rb +3503 -0
- data/lib/logstash/config/mixin.rb +495 -0
- data/lib/logstash/config/registry.rb +13 -0
- data/lib/logstash/environment.rb +168 -0
- data/lib/logstash/errors.rb +12 -0
- data/lib/logstash/event.rb +310 -0
- data/lib/logstash/filters/base.rb +239 -0
- data/lib/logstash/gemfile.rb +175 -0
- data/lib/logstash/inputs/base.rb +137 -0
- data/lib/logstash/inputs/threadable.rb +18 -0
- data/lib/logstash/java_integration.rb +41 -0
- data/lib/logstash/json.rb +53 -0
- data/lib/logstash/logging.rb +91 -0
- data/lib/logstash/multiqueue.rb +53 -0
- data/lib/logstash/namespace.rb +17 -0
- data/lib/logstash/outputs/base.rb +124 -0
- data/lib/logstash/patches.rb +3 -0
- data/lib/logstash/patches/bugfix_jruby_2558.rb +50 -0
- data/lib/logstash/patches/cabin.rb +34 -0
- data/lib/logstash/patches/profile_require_calls.rb +47 -0
- data/lib/logstash/pipeline.rb +305 -0
- data/lib/logstash/plugin.rb +177 -0
- data/lib/logstash/pluginmanager.rb +17 -0
- data/lib/logstash/pluginmanager/install.rb +112 -0
- data/lib/logstash/pluginmanager/list.rb +38 -0
- data/lib/logstash/pluginmanager/main.rb +22 -0
- data/lib/logstash/pluginmanager/maven_tools_patch.rb +12 -0
- data/lib/logstash/pluginmanager/uninstall.rb +49 -0
- data/lib/logstash/pluginmanager/update.rb +50 -0
- data/lib/logstash/pluginmanager/util.rb +88 -0
- data/lib/logstash/program.rb +15 -0
- data/lib/logstash/runner.rb +167 -0
- data/lib/logstash/sized_queue.rb +8 -0
- data/lib/logstash/threadwatchdog.rb +37 -0
- data/lib/logstash/timestamp.rb +97 -0
- data/lib/logstash/util.rb +152 -0
- data/lib/logstash/util/accessors.rb +88 -0
- data/lib/logstash/util/buftok.rb +139 -0
- data/lib/logstash/util/charset.rb +35 -0
- data/lib/logstash/util/fieldreference.rb +68 -0
- data/lib/logstash/util/filetools.rb +185 -0
- data/lib/logstash/util/password.rb +25 -0
- data/lib/logstash/util/plugin_version.rb +43 -0
- data/lib/logstash/util/prctl.rb +11 -0
- data/lib/logstash/util/require-helper.rb +18 -0
- data/lib/logstash/util/retryable.rb +39 -0
- data/lib/logstash/util/socket_peer.rb +7 -0
- data/lib/logstash/version.rb +6 -0
- data/locales/en.yml +176 -0
- metadata +427 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/inputs/base"
|
4
|
+
|
5
|
+
# This is the threadable class for logstash inputs.
|
6
|
+
# Use this class in your inputs if it can support multiple threads
|
7
|
+
class LogStash::Inputs::Threadable < LogStash::Inputs::Base
|
8
|
+
|
9
|
+
# Set this to the number of threads you want this input to spawn.
|
10
|
+
# This is the same as declaring the input multiple times
|
11
|
+
config :threads, :validate => :number, :default => 1
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
super
|
15
|
+
@threadable = true
|
16
|
+
end
|
17
|
+
|
18
|
+
end # class LogStash::Inputs::Threadable
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "java"
|
2
|
+
|
3
|
+
# this is mainly for usage with JrJackson json parsing in :raw mode which genenerates
|
4
|
+
# Java::JavaUtil::ArrayList and Java::JavaUtil::LinkedHashMap native objects for speed.
|
5
|
+
# these object already quacks like their Ruby equivalents Array and Hash but they will
|
6
|
+
# not test for is_a?(Array) or is_a?(Hash) and we do not want to include tests for
|
7
|
+
# both classes everywhere. see LogStash::JSon.
|
8
|
+
|
9
|
+
class Java::JavaUtil::ArrayList
|
10
|
+
# have ArrayList objects report is_a?(Array) == true
|
11
|
+
def is_a?(clazz)
|
12
|
+
return true if clazz == Array
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Java::JavaUtil::LinkedHashMap
|
18
|
+
# have LinkedHashMap objects report is_a?(Array) == true
|
19
|
+
def is_a?(clazz)
|
20
|
+
return true if clazz == Hash
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Array
|
26
|
+
# enable class equivalence between Array and ArrayList
|
27
|
+
# so that ArrayList will work with case o when Array ...
|
28
|
+
def self.===(other)
|
29
|
+
return true if other.is_a?(Java::JavaUtil::ArrayList)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Hash
|
35
|
+
# enable class equivalence between Hash and LinkedHashMap
|
36
|
+
# so that LinkedHashMap will work with case o when Hash ...
|
37
|
+
def self.===(other)
|
38
|
+
return true if other.is_a?(Java::JavaUtil::LinkedHashMap)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/environment"
|
3
|
+
require "logstash/errors"
|
4
|
+
if LogStash::Environment.jruby?
|
5
|
+
require "jrjackson"
|
6
|
+
require "logstash/java_integration"
|
7
|
+
else
|
8
|
+
require "oj"
|
9
|
+
end
|
10
|
+
|
11
|
+
module LogStash
|
12
|
+
module Json
|
13
|
+
class ParserError < LogStash::Error; end
|
14
|
+
class GeneratorError < LogStash::Error; end
|
15
|
+
|
16
|
+
extend self
|
17
|
+
|
18
|
+
### MRI
|
19
|
+
|
20
|
+
def mri_load(data, options = {})
|
21
|
+
Oj.load(data)
|
22
|
+
rescue Oj::ParseError => e
|
23
|
+
raise LogStash::Json::ParserError.new(e.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def mri_dump(o)
|
27
|
+
Oj.dump(o, :mode => :compat, :use_to_json => true)
|
28
|
+
rescue => e
|
29
|
+
raise LogStash::Json::GeneratorError.new(e.message)
|
30
|
+
end
|
31
|
+
|
32
|
+
### JRuby
|
33
|
+
|
34
|
+
def jruby_load(data, options = {})
|
35
|
+
options[:symbolize_keys] ? JrJackson::Raw.parse_sym(data) : JrJackson::Raw.parse_raw(data)
|
36
|
+
rescue JrJackson::ParseError => e
|
37
|
+
raise LogStash::Json::ParserError.new(e.message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def jruby_dump(o)
|
41
|
+
# test for enumerable here to work around an omission in JrJackson::Json.dump to
|
42
|
+
# also look for Java::JavaUtil::ArrayList, see TODO submit issue
|
43
|
+
o.is_a?(Enumerable) ? JrJackson::Raw.generate(o) : JrJackson::Json.dump(o)
|
44
|
+
rescue => e
|
45
|
+
raise LogStash::Json::GeneratorError.new(e.message)
|
46
|
+
end
|
47
|
+
|
48
|
+
prefix = LogStash::Environment.jruby? ? "jruby" : "mri"
|
49
|
+
alias_method :load, "#{prefix}_load".to_sym
|
50
|
+
alias_method :dump, "#{prefix}_dump".to_sym
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "cabin"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
class LogStash::Logger
|
7
|
+
attr_accessor :target
|
8
|
+
|
9
|
+
public
|
10
|
+
def initialize(*args)
|
11
|
+
super()
|
12
|
+
|
13
|
+
#self[:program] = File.basename($0)
|
14
|
+
#subscribe(::Logger.new(*args))
|
15
|
+
@target = args[0]
|
16
|
+
@channel = Cabin::Channel.get(LogStash)
|
17
|
+
|
18
|
+
# lame hack until cabin's smart enough not to doubley-subscribe something.
|
19
|
+
# without this subscription count check, running the test suite
|
20
|
+
# causes Cabin to subscribe to STDOUT maaaaaany times.
|
21
|
+
subscriptions = @channel.instance_eval { @subscribers.count }
|
22
|
+
@channel.subscribe(@target) unless subscriptions > 0
|
23
|
+
|
24
|
+
# Set default loglevel to WARN unless $DEBUG is set (run with 'ruby -d')
|
25
|
+
@level = $DEBUG ? :debug : :warn
|
26
|
+
if ENV["LOGSTASH_DEBUG"]
|
27
|
+
@level = :debug
|
28
|
+
end
|
29
|
+
|
30
|
+
# Direct metrics elsewhere.
|
31
|
+
@channel.metrics.channel = Cabin::Channel.new
|
32
|
+
end # def initialize
|
33
|
+
|
34
|
+
# Delegation
|
35
|
+
def level=(value) @channel.level = value; end
|
36
|
+
def debug(*args); @channel.debug(*args); end
|
37
|
+
def debug?(*args); @channel.debug?(*args); end
|
38
|
+
def info(*args); @channel.info(*args); end
|
39
|
+
def info?(*args); @channel.info?(*args); end
|
40
|
+
def warn(*args); @channel.warn(*args); end
|
41
|
+
def warn?(*args); @channel.warn?(*args); end
|
42
|
+
def error(*args); @channel.error(*args); end
|
43
|
+
def error?(*args); @channel.error?(*args); end
|
44
|
+
def fatal(*args); @channel.fatal(*args); end
|
45
|
+
def fatal?(*args); @channel.fatal?(*args); end
|
46
|
+
|
47
|
+
def self.setup_log4j(logger)
|
48
|
+
require "java"
|
49
|
+
|
50
|
+
properties = java.util.Properties.new
|
51
|
+
log4j_level = "WARN"
|
52
|
+
case logger.level
|
53
|
+
when :debug
|
54
|
+
log4j_level = "DEBUG"
|
55
|
+
when :info
|
56
|
+
log4j_level = "INFO"
|
57
|
+
when :warn
|
58
|
+
log4j_level = "WARN"
|
59
|
+
end # case level
|
60
|
+
properties.setProperty("log4j.rootLogger", "#{log4j_level},logstash")
|
61
|
+
|
62
|
+
# TODO(sissel): This is a shitty hack to work around the fact that
|
63
|
+
# LogStash::Logger isn't used anymore. We should fix that.
|
64
|
+
target = logger.instance_eval { @subscribers }.values.first.instance_eval { @io }
|
65
|
+
case target
|
66
|
+
when STDOUT
|
67
|
+
properties.setProperty("log4j.appender.logstash",
|
68
|
+
"org.apache.log4j.ConsoleAppender")
|
69
|
+
properties.setProperty("log4j.appender.logstash.Target", "System.out")
|
70
|
+
when STDERR
|
71
|
+
properties.setProperty("log4j.appender.logstash",
|
72
|
+
"org.apache.log4j.ConsoleAppender")
|
73
|
+
properties.setProperty("log4j.appender.logstash.Target", "System.err")
|
74
|
+
when target.is_a?(File)
|
75
|
+
properties.setProperty("log4j.appender.logstash",
|
76
|
+
"org.apache.log4j.FileAppender")
|
77
|
+
properties.setProperty("log4j.appender.logstash.File", target.path)
|
78
|
+
else
|
79
|
+
properties.setProperty("log4j.appender.logstash", "org.apache.log4j.varia.NullAppender")
|
80
|
+
end # case target
|
81
|
+
|
82
|
+
properties.setProperty("log4j.appender.logstash.layout",
|
83
|
+
"org.apache.log4j.PatternLayout")
|
84
|
+
properties.setProperty("log4j.appender.logstash.layout.conversionPattern",
|
85
|
+
"log4j, [%d{yyyy-MM-dd}T%d{HH:mm:ss.SSS}] %5p: %c: %m%n")
|
86
|
+
|
87
|
+
org.apache.log4j.LogManager.resetConfiguration
|
88
|
+
org.apache.log4j.PropertyConfigurator.configure(properties)
|
89
|
+
logger.debug("log4j java properties setup", :log4j_level => log4j_level)
|
90
|
+
end
|
91
|
+
end # class LogStash::Logger
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "cabin"
|
4
|
+
|
5
|
+
class LogStash::MultiQueue
|
6
|
+
attr_accessor :logger
|
7
|
+
|
8
|
+
public
|
9
|
+
def initialize(*queues)
|
10
|
+
@logger = Cabin::Channel.get(LogStash)
|
11
|
+
@mutex = Mutex.new
|
12
|
+
@queues = queues
|
13
|
+
end # def initialize
|
14
|
+
|
15
|
+
public
|
16
|
+
def logger=(_logger)
|
17
|
+
@logger = _logger
|
18
|
+
|
19
|
+
# Set the logger for all known queues, too.
|
20
|
+
@queues.each do |q|
|
21
|
+
q.logger = _logger
|
22
|
+
end
|
23
|
+
end # def logger=
|
24
|
+
|
25
|
+
# Push an object to all queues.
|
26
|
+
public
|
27
|
+
def push(object)
|
28
|
+
@queues.each { |q| q.push(object) }
|
29
|
+
end # def push
|
30
|
+
alias :<< :push
|
31
|
+
|
32
|
+
alias_method :<<, :push
|
33
|
+
|
34
|
+
# Add a new Queue to this queue.
|
35
|
+
public
|
36
|
+
def add_queue(queue)
|
37
|
+
@mutex.synchronize do
|
38
|
+
@queues << queue
|
39
|
+
end
|
40
|
+
end # def add_queue
|
41
|
+
|
42
|
+
public
|
43
|
+
def remove_queue(queue)
|
44
|
+
@mutex.synchronize do
|
45
|
+
@queues.delete(queue)
|
46
|
+
end
|
47
|
+
end # def remove_queue
|
48
|
+
|
49
|
+
public
|
50
|
+
def size
|
51
|
+
return @queues.collect { |q| q.size }
|
52
|
+
end # def size
|
53
|
+
end # class LogStash::MultiQueue
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#$: << File.join(File.dirname(__FILE__), "..", "..", "vendor", "bundle")
|
3
|
+
|
4
|
+
module LogStash
|
5
|
+
module Inputs; end
|
6
|
+
module Outputs; end
|
7
|
+
module Filters; end
|
8
|
+
module Search; end
|
9
|
+
module Config; end
|
10
|
+
module File; end
|
11
|
+
module Web; end
|
12
|
+
module Util; end
|
13
|
+
module PluginMixins; end
|
14
|
+
module PluginManager; end
|
15
|
+
|
16
|
+
SHUTDOWN = :shutdown
|
17
|
+
end # module LogStash
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "cgi"
|
3
|
+
require "logstash/event"
|
4
|
+
require "logstash/logging"
|
5
|
+
require "logstash/plugin"
|
6
|
+
require "logstash/namespace"
|
7
|
+
require "logstash/config/mixin"
|
8
|
+
require "uri"
|
9
|
+
|
10
|
+
class LogStash::Outputs::Base < LogStash::Plugin
|
11
|
+
include LogStash::Config::Mixin
|
12
|
+
|
13
|
+
config_name "output"
|
14
|
+
|
15
|
+
# The type to act on. If a type is given, then this output 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
|
+
# The codec used for output data. Output codecs are a convenient method for encoding your data before it leaves the output, without needing a separate filter in your Logstash pipeline.
|
30
|
+
config :codec, :validate => :codec, :default => "plain"
|
31
|
+
|
32
|
+
# The number of workers to use for this output.
|
33
|
+
# Note that this setting may not be useful for all outputs.
|
34
|
+
config :workers, :validate => :number, :default => 1
|
35
|
+
|
36
|
+
attr_reader :worker_plugins
|
37
|
+
|
38
|
+
public
|
39
|
+
def workers_not_supported(message=nil)
|
40
|
+
return if @workers == 1
|
41
|
+
if message
|
42
|
+
@logger.warn(I18n.t("logstash.pipeline.output-worker-unsupported-with-message", :plugin => self.class.config_name, :worker_count => @workers, :message => message))
|
43
|
+
else
|
44
|
+
@logger.warn(I18n.t("logstash.pipeline.output-worker-unsupported", :plugin => self.class.config_name, :worker_count => @workers))
|
45
|
+
end
|
46
|
+
@workers = 1
|
47
|
+
end
|
48
|
+
|
49
|
+
public
|
50
|
+
def initialize(params={})
|
51
|
+
super
|
52
|
+
config_init(params)
|
53
|
+
end
|
54
|
+
|
55
|
+
public
|
56
|
+
def register
|
57
|
+
raise "#{self.class}#register must be overidden"
|
58
|
+
end # def register
|
59
|
+
|
60
|
+
public
|
61
|
+
def receive(event)
|
62
|
+
raise "#{self.class}#receive must be overidden"
|
63
|
+
end # def receive
|
64
|
+
|
65
|
+
public
|
66
|
+
def worker_setup
|
67
|
+
if @workers == 1
|
68
|
+
@worker_plugins = [self]
|
69
|
+
else
|
70
|
+
define_singleton_method(:handle, method(:handle_worker))
|
71
|
+
@worker_queue = SizedQueue.new(20)
|
72
|
+
@worker_plugins = @workers.times.map { self.class.new(params.merge("workers" => 1, "codec" => @codec.clone)) }
|
73
|
+
@worker_plugins.map.with_index do |plugin, i|
|
74
|
+
Thread.new(original_params, @worker_queue) do |params, queue|
|
75
|
+
LogStash::Util::set_thread_name(">#{self.class.config_name}.#{i}")
|
76
|
+
plugin.register
|
77
|
+
while true
|
78
|
+
event = queue.pop
|
79
|
+
plugin.handle(event)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
public
|
87
|
+
def handle(event)
|
88
|
+
receive(event)
|
89
|
+
end # def handle
|
90
|
+
|
91
|
+
def handle_worker(event)
|
92
|
+
@worker_queue.push(event)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def output?(event)
|
97
|
+
if !@type.empty?
|
98
|
+
if event["type"] != @type
|
99
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because type doesn't match",
|
100
|
+
:type => @type, :event => event)
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if !@tags.empty?
|
106
|
+
return false if !event["tags"]
|
107
|
+
if (event["tags"] & @tags).size != @tags.size
|
108
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because tags don't match",
|
109
|
+
:tags => @tags, :event => event)
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if !@exclude_tags.empty? && event["tags"]
|
115
|
+
if (diff_tags = (event["tags"] & @exclude_tags)).size != 0
|
116
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because tags contains excluded tags",
|
117
|
+
:diff_tags => diff_tags, :exclude_tags => @exclude_tags, :event => event)
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
return true
|
123
|
+
end
|
124
|
+
end # class LogStash::Outputs::Base
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "logstash/environment"
|
2
|
+
|
3
|
+
if LogStash::Environment.windows? && LogStash::Environment.jruby?
|
4
|
+
require "socket"
|
5
|
+
module JRubyBug2558SocketPeerAddrBugFix
|
6
|
+
def peeraddr
|
7
|
+
orig_peeraddr.map do |v|
|
8
|
+
case v
|
9
|
+
when String
|
10
|
+
v.force_encoding(Encoding::UTF_8)
|
11
|
+
else
|
12
|
+
v
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class << Socket
|
19
|
+
# Bugfix for jruby #2558
|
20
|
+
alias_method :orig_gethostname, :gethostname
|
21
|
+
def gethostname
|
22
|
+
return orig_gethostname.force_encoding(Encoding::UTF_8)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class TCPSocket
|
27
|
+
alias_method :orig_peeraddr, :peeraddr
|
28
|
+
include JRubyBug2558SocketPeerAddrBugFix
|
29
|
+
end
|
30
|
+
class UDPSocket
|
31
|
+
alias_method :orig_peeraddr, :peeraddr
|
32
|
+
include JRubyBug2558SocketPeerAddrBugFix
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if LogStash::Environment.windows?
|
37
|
+
# make sure all strings pulled out of ENV are UTF8
|
38
|
+
class <<ENV
|
39
|
+
alias_method :orig_getter, :[]
|
40
|
+
def [](key)
|
41
|
+
case value = orig_getter(key)
|
42
|
+
when String
|
43
|
+
# dup is necessary since force_encoding is destructive
|
44
|
+
value.dup.force_encoding(Encoding::UTF_8)
|
45
|
+
else
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|